Added new concept of a tuning database; tryout phase
[hashcat.git] / tools / test.sh
1 #!/usr/bin/env bash
2
3 ##
4 ## Authors.....: Gabriele Gristina <matrix@hashcat.net>
5 ## Jens Steube <jens.steube@gmail.com>
6 ##
7 ## License.....: MIT
8 ##
9
10 # missing hash types: 5200,6211,6221,6231,6241,6251,6261,6271,6281
11
12 HASH_TYPES="0 10 11 12 20 21 22 23 30 40 50 60 100 101 110 111 112 120 121 122 130 131 132 140 141 150 160 190 200 300 400 500 900 1000 1100 1400 1410 1420 1430 1440 1441 1450 1460 1500 1600 1700 1710 1711 1720 1722 1730 1731 1740 1750 1760 1800 2100 2400 2410 2500 2600 2611 2612 2711 2811 3000 3100 3200 3710 3711 3800 4300 4400 4500 4700 4800 4900 5000 5100 5300 5400 5500 5600 5700 5800 6000 6100 6300 6400 6500 6600 6700 6800 6900 7100 7200 7300 7400 7500 7600 7700 7800 7900 8000 8100 8200 8300 8400 8500 8600 8700 8900 9100 9200 9300 9400 9500 9600 9700 9800 9900 10000 10100 10200 10300 10400 10500 10600 10700 10800 10900 11000 11100 11200 11300 11400 11500 11600 11900 12000 12100 12200 12300 12400 12600 12800 12900 13000"
13
14 #ATTACK_MODES="0 1 3 6 7"
15 ATTACK_MODES="0 1 3 7"
16
17 VECTOR_WIDTHS="1 2 4 8"
18
19 MATCH_PASS_ONLY="2500 5300 5400 6600 6800 8200"
20
21 HASHFILE_ONLY="2500"
22
23 NEVER_CRACK="11600"
24
25 SLOW_ALGOS="400 500 501 1600 1800 2100 2500 3200 5200 5800 6211 6221 6231 6241 6251 6261 6271 6281 6300 6400 6500 6600 6700 6800 7100 7200 7400 7900 8200 8800 8900 9000 9100 9200 9300 9400 9500 9600 10000 10300 10500 10700 10900 11300 11600 11900 12000 12100 12200 12300 12400 12500 12800 12900 13000"
26
27 OPTS="--quiet --force --potfile-disable --runtime 200 --gpu-temp-disable --weak-hash-threshold=0"
28
29 OUTD="test_$(date +%s)"
30
31 PACKAGE_CMD="7z a"
32 PACKAGE_FOLDER=""
33
34 mask_3[0]=""
35 mask_3[1]="?d"
36 mask_3[2]="?d?d"
37 mask_3[3]="?d?d?d"
38 mask_3[4]="?d?d?d?d"
39 mask_3[5]="?d?d?d?d?d"
40 mask_3[6]="?d?d?d?d?d?d"
41 mask_3[7]="?d?d?d?d?d?d?d"
42 mask_3[8]="?d?d?d?d?d?d?d?d"
43 mask_3[9]="?d?d?d?d?d?d?d?d?d"
44 mask_3[10]="?d?d?d?d?d?d?d?d?d?d"
45 mask_3[11]="?d?d?d?d?d?d?d?d?d?d?d"
46 mask_3[12]="?d?d?d?d?d?d?d?d?d?d?d?d"
47 mask_3[13]="?d?d?d?d?d?d?d?d?d?d?d?d?d"
48 mask_3[14]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d"
49 mask_3[15]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d"
50 mask_3[16]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0"
51 mask_3[17]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d00"
52 mask_3[18]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d000"
53 mask_3[19]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0000"
54 mask_3[20]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d00000"
55 mask_3[21]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d000000"
56 mask_3[22]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0000000"
57 mask_3[23]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d00000000"
58 mask_3[24]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d000000000"
59 mask_3[25]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0000000000"
60 mask_3[26]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d00000000000"
61 mask_3[27]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d000000000000"
62 mask_3[28]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0000000000000"
63 mask_3[29]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d00000000000000"
64 mask_3[30]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d000000000000000"
65 mask_3[31]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0000000000000000"
66
67 mask_6[0]=""
68 mask_6[1]=""
69 mask_6[2]="?d"
70 mask_6[3]="?d?d"
71 mask_6[4]="?d?d"
72 mask_6[5]="?d?d?d"
73 mask_6[6]="?d?d?d"
74 mask_6[7]="?d?d?d?d"
75 mask_6[8]="?d?d?d?d"
76 mask_6[9]="?d?d?d?d?d"
77 mask_6[10]="?d?d?d?d?d"
78 mask_6[11]="?d?d?d?d?d?d"
79 mask_6[12]="?d?d?d?d?d?d"
80 mask_6[13]="?d?d?d?d?d?d?d"
81 mask_6[14]="?d?d?d?d?d?d?d"
82 mask_6[15]="?d?d?d?d?d?d?d?d"
83 mask_6[16]="?d?d?d?d?d?d?d?d"
84 mask_6[17]="?d?d?d?d?d?d?d?d0"
85 mask_6[18]="?d?d?d?d?d?d?d?d0"
86 mask_6[19]="?d?d?d?d?d?d?d?d00"
87 mask_6[20]="?d?d?d?d?d?d?d?d00"
88 mask_6[21]="?d?d?d?d?d?d?d?d000"
89 mask_6[22]="?d?d?d?d?d?d?d?d000"
90 mask_6[23]="?d?d?d?d?d?d?d?d0000"
91 mask_6[24]="?d?d?d?d?d?d?d?d0000"
92 mask_6[25]="?d?d?d?d?d?d?d?d00000"
93 mask_6[26]="?d?d?d?d?d?d?d?d00000"
94 mask_6[27]="?d?d?d?d?d?d?d?d000000"
95 mask_6[28]="?d?d?d?d?d?d?d?d000000"
96 mask_6[29]="?d?d?d?d?d?d?d?d0000000"
97 mask_6[30]="?d?d?d?d?d?d?d?d0000000"
98 mask_6[31]="?d?d?d?d?d?d?d?d00000000"
99
100 mask_7[0]=""
101 mask_7[1]=""
102 mask_7[2]="?d"
103 mask_7[3]="?d"
104 mask_7[4]="?d?d"
105 mask_7[5]="?d?d"
106 mask_7[6]="?d?d?d"
107 mask_7[7]="?d?d?d"
108 mask_7[8]="?d?d?d?d"
109 mask_7[9]="?d?d?d?d"
110 mask_7[10]="?d?d?d?d?d"
111 mask_7[11]="?d?d?d?d?d"
112 mask_7[12]="?d?d?d?d?d?d"
113 mask_7[13]="?d?d?d?d?d?d"
114 mask_7[14]="?d?d?d?d?d?d?d"
115 mask_7[15]="?d?d?d?d?d?d?d"
116 mask_7[16]="?d?d?d?d?d?d?d?d"
117 mask_7[17]="?d?d?d?d?d?d?d?d"
118 mask_7[18]="?d?d?d?d?d?d?d?d0"
119 mask_7[19]="?d?d?d?d?d?d?d?d0"
120 mask_7[20]="?d?d?d?d?d?d?d?d00"
121 mask_7[21]="?d?d?d?d?d?d?d?d00"
122 mask_7[22]="?d?d?d?d?d?d?d?d000"
123 mask_7[23]="?d?d?d?d?d?d?d?d000"
124 mask_7[24]="?d?d?d?d?d?d?d?d0000"
125 mask_7[25]="?d?d?d?d?d?d?d?d0000"
126 mask_7[26]="?d?d?d?d?d?d?d?d00000"
127 mask_7[27]="?d?d?d?d?d?d?d?d00000"
128 mask_7[28]="?d?d?d?d?d?d?d?d000000"
129 mask_7[29]="?d?d?d?d?d?d?d?d000000"
130 mask_7[30]="?d?d?d?d?d?d?d?d0000000"
131 mask_7[31]="?d?d?d?d?d?d?d?d0000000"
132
133 contains ()
134 {
135 for element in "${@:2}"; do
136
137 if [ "${element}" == "${1}" ]; then
138 return 1
139 fi
140
141 done
142
143 return 0
144 }
145
146 function init()
147 {
148 if [ "${PACKAGE}" -eq 1 ]; then
149
150 echo "[ ${OUTD} ] > Generate tests for hash type $hash_type."
151
152 else
153
154 echo "[ ${OUTD} ] > Init test for hash type $hash_type."
155
156 fi
157
158 rm -rf ${OUTD}/${hash_type}.sh ${OUTD}/${hash_type}_passwords.txt ${OUTD}/${hash_type}_hashes.txt
159
160 # create list of password and hashes of same type
161 grep " ${hash_type} '" ${OUTD}/all.sh > ${OUTD}/${hash_type}.sh
162
163 # create separate list of password and hashes
164 cat ${OUTD}/${hash_type}.sh | awk '{print $3}' > ${OUTD}/${hash_type}_passwords.txt
165 cat ${OUTD}/${hash_type}.sh | awk '{print $11}' | cut -d"'" -f2 > ${OUTD}/${hash_type}_hashes.txt
166
167 if [ "${hash_type}" -eq 10300 ]; then
168 cat ${OUTD}/${hash_type}.sh | cut -d' ' -f11- | cut -d"'" -f2 > ${OUTD}/${hash_type}_hashes.txt
169 fi
170
171 # truncate dicts
172 rm -rf ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2
173 touch ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2
174
175 # foreach password entry split password in 2 (skip first entry, is len 1)
176 i=1
177
178 # minimum password length
179
180 min_len=0
181
182 if [ "${hash_type}" -eq 2500 ]; then
183
184 min_len=7 # means length 8, since we start with 0
185
186 fi
187
188 while read -u 9 pass; do
189
190 if [ ${i} -gt 1 ]; then
191
192 # split password, 'i' is the len
193 p0=$((i / 2))
194 p1=$((p0 + 1))
195
196 # special case (passwords longer than expected)
197 pass_len=${#pass}
198
199 if [ "${pass_len}" -gt 1 ]
200 then
201
202 p1=$((p1 + ${min_len}))
203 p0=$((p0 + ${min_len}))
204
205 if [ "${p1}" -gt ${pass_len} ]; then
206
207 p1=${pass_len}
208 p0=$((p1 - 1))
209
210 fi
211
212 # add splitted password to dicts
213
214 echo ${pass} | cut -c -${p0} >> ${OUTD}/${hash_type}_dict1
215 echo ${pass} | cut -c ${p1}- >> ${OUTD}/${hash_type}_dict2
216
217 fi
218 fi
219
220 ((i++))
221
222 done 9< ${OUTD}/${hash_type}_passwords.txt
223
224 min_len=0
225
226 if [ "${hash_type}" -eq 2500 ]; then
227
228 min_len=7 # means length 8, since we start with 0
229
230 fi
231
232 # generate multiple pass/hash foreach len (2 to 8)
233 if [ ${MODE} -ge 1 ]; then
234
235 for ((i = 2; i < 9; i++)); do
236
237 rm -rf ${OUTD}/${hash_type}_multi_${i}.txt ${OUTD}/${hash_type}_passwords_multi_${i}.txt ${OUTD}/${hash_type}_hashes_multi_${i}.txt
238 rm -rf ${OUTD}/${hash_type}_dict1_multi_${i} ${OUTD}/${hash_type}_dict2_multi_${i}
239 touch ${OUTD}/${hash_type}_dict1_multi_${i} ${OUTD}/${hash_type}_dict2_multi_${i}
240
241 perl tools/test.pl single ${hash_type} ${i} > ${OUTD}/${hash_type}_multi_${i}.txt
242
243 cat ${OUTD}/${hash_type}_multi_${i}.txt | awk '{print $3}' > ${OUTD}/${hash_type}_passwords_multi_${i}.txt
244 cat ${OUTD}/${hash_type}_multi_${i}.txt | awk '{print $11}' | cut -d"'" -f2 > ${OUTD}/${hash_type}_hashes_multi_${i}.txt
245
246 if [ "${hash_type}" -eq 10300 ]; then
247 cat ${OUTD}/${hash_type}_multi_${i}.txt | cut -d' ' -f11- | cut -d"'" -f2 > ${OUTD}/${hash_type}_hashes_multi_${i}.txt
248 fi
249
250 # split password, 'i' is the len
251 p0=$((i / 2))
252 p1=$((p0 + 1))
253
254 p0=$((p0 + ${min_len}))
255 p1=$((p1 + ${min_len}))
256
257 while read -u 9 pass; do
258
259 # add splitted password to dicts
260 echo ${pass} | cut -c -${p0} >> ${OUTD}/${hash_type}_dict1_multi_${i}
261 echo ${pass} | cut -c ${p1}- >> ${OUTD}/${hash_type}_dict2_multi_${i}
262
263 done 9< ${OUTD}/${hash_type}_passwords_multi_${i}.txt
264
265 done
266
267 fi
268 }
269
270 function status()
271 {
272 RET=$1
273
274 ((cnt++))
275
276 if [ ${RET} -ne 0 ]; then
277 case ${RET} in
278 1)
279 if contains ${hash_type} ${NEVER_CRACK_ALGOS}; then
280
281 echo "password not found, cmdline : ${CMD}" &>> ${OUTD}/logfull.txt
282 ((e_nf++))
283
284 fi
285
286 ;;
287 2)
288 echo "timeout reached, cmdline : ${CMD}" &>> ${OUTD}/logfull.txt
289 ((e_to++))
290
291 ;;
292 10)
293 if [ "${pass_only}" -eq 1 ]; then
294 echo "plains not found in output, cmdline : ${CMD}" &>> ${OUTD}/logfull.txt
295 else
296 echo "hash:plains not matched in output, cmdline : ${CMD}" &>> ${OUTD}/logfull.txt
297 fi
298 ((e_nm++))
299
300 ;;
301 *)
302 echo "! unhandled return code ${RET}, cmdline : ${CMD}" &>> ${OUTD}/logfull.txt
303 echo "! unhandled return code, see ${OUTD}/logfull.txt for details."
304 ((e_nf++))
305 ;;
306 esac
307 fi
308 }
309
310 function attack_0()
311 {
312 file_only=0
313
314 if ! contains ${hash_type} ${FILE_BASED_ALGOS}; then
315
316 file_only=1
317
318 fi
319
320 # single hash
321 if [ ${MODE} -ne 1 ]; then
322
323 e_to=0
324 e_nf=0
325 e_nm=0
326 cnt=0
327
328 echo "> Testing hash type $hash_type with attack mode 0, markov ${MARKOV}, single hash, device-type ${TYPE}, vector-width ${VECTOR}." &>> ${OUTD}/logfull.txt
329
330 max=32
331
332 if ! contains ${hash_type} ${TIMEOUT_ALGOS}; then
333
334 max=12
335
336 fi
337
338 i=0
339
340 while read -u 9 line; do
341
342 if [ "${i}" -ge ${max} ]; then
343
344 break
345
346 fi
347
348 hash="$(echo "$line" | cut -d\' -f2)"
349 pass="$(echo "$line" | cut -d' ' -f3)"
350
351 if [ -z "${hash}" ]; then
352
353 break
354
355 fi
356
357 if [ "${file_only}" -eq 1 ]; then
358
359 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
360 echo ${hash} | base64 -d > ${temp_file}
361 hash="${temp_file}"
362
363 fi
364
365 CMD="echo -n "${pass}" | ./${BIN} ${OPTS} -a 0 -m ${hash_type} '${hash}'"
366
367 echo -n "[ len $((i + 1)) ] " &>> ${OUTD}/logfull.txt
368
369 output=$(echo -n "${pass}" | ./${BIN} ${OPTS} -a 0 -m ${hash_type} "${hash}" 2>&1)
370
371 ret=${?}
372
373 echo "${output}" >> ${OUTD}/logfull.txt
374
375 if [ "${ret}" -eq 0 ]; then
376
377 if [ ${pass_only} -eq 1 ]; then
378 search=":${pass}"
379 else
380 search="${hash}:${pass}"
381 fi
382
383 echo "${output}" | grep -F "${search}" &> /dev/null
384
385 if [ "${?}" -ne 0 ]; then
386
387 ret=10
388
389 fi
390
391 fi
392
393 status ${ret}
394
395 i=$((i + 1))
396
397 done 9< ${OUTD}/${hash_type}.sh
398
399 msg="OK"
400
401 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
402
403 msg="Error"
404
405 elif [ "${e_to}" -ne 0 ]; then
406
407 msg="Warning"
408
409 fi
410
411 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 0, Mode single, Device-Type ${TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
412
413 fi
414
415 # multihash
416 if [ ${MODE} -ne 0 ]; then
417
418 e_to=0
419 e_nf=0
420 e_nm=0
421 cnt=0
422
423 echo "> Testing hash type $hash_type with attack mode 0, markov ${MARKOV}, multi hash, Device-Type ${TYPE}, vector-width ${VECTOR}." &>> ${OUTD}/logfull.txt
424
425 hash_file=${OUTD}/${hash_type}_hashes.txt
426
427 # if file_only -> decode all base64 "hashes" and put them in the temporary file
428
429 if [ "${file_only}" -eq 1 ]; then
430
431 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
432 rm -f ${temp_file}
433
434 hash_file=${temp_file}
435
436 while read base64_hash; do
437
438 echo -n ${base64_hash} | base64 -d >> ${temp_file}
439
440 done < ${OUTD}/${hash_type}_hashes.txt
441
442 fi
443
444 CMD="cat ${OUTD}/${hash_type}_passwords.txt | ./${BIN} ${OPTS} -a 0 -m ${hash_type} ${hash_file}"
445
446 output=$(cat ${OUTD}/${hash_type}_passwords.txt | ./${BIN} ${OPTS} -a 0 -m ${hash_type} ${hash_file} 2>&1)
447
448 ret=${?}
449
450 echo "${output}" >> ${OUTD}/logfull.txt
451
452 if [ "${ret}" -eq 0 ]; then
453
454 i=1
455
456 while read -u 9 hash; do
457
458 pass=$(sed -n ${i}p ${OUTD}/${hash_type}_passwords.txt)
459
460 if [ ${pass_only} -eq 1 ]; then
461 search=":${pass}"
462 else
463 search="${hash}:${pass}"
464 fi
465
466 echo "${output}" | grep -F "${search}" &> /dev/null
467
468 if [ "${?}" -ne 0 ]; then
469
470 ret=10
471
472 break
473
474 fi
475
476 i=$((i + 1))
477
478 done 9< ${OUTD}/${hash_type}_hashes.txt
479
480 fi
481
482 status ${ret}
483
484 msg="OK"
485
486 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
487
488 msg="Error"
489
490 elif [ "${e_to}" -ne 0 ]; then
491
492 msg="Warning"
493
494 fi
495
496 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 0, Mode multi, Device-Type ${TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
497
498 fi
499 }
500
501 function attack_1()
502 {
503 file_only=0
504
505 if ! contains ${hash_type} ${FILE_BASED_ALGOS}; then
506
507 file_only=1
508
509 fi
510
511 # single hash
512 if [ ${MODE} -ne 1 ]; then
513
514 e_to=0
515 e_nf=0
516 e_nm=0
517 cnt=0
518
519 echo "> Testing hash type $hash_type with attack mode 1, markov ${MARKOV}, single hash, Device-Type ${TYPE}, vector-width ${VECTOR}." &>> ${OUTD}/logfull.txt
520 i=1
521 while read -u 9 hash; do
522
523 if [ $i -gt 1 ]; then
524
525 if [ "${file_only}" -eq 1 ]; then
526
527 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
528 echo ${hash} | base64 -d > ${temp_file}
529 hash="${temp_file}"
530
531 fi
532
533 CMD="./${BIN} ${OPTS} -a 1 -m ${hash_type} '${hash}' ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2"
534
535 echo -n "[ len $i ] " &>> ${OUTD}/logfull.txt
536
537 output=$(./${BIN} ${OPTS} -a 1 -m ${hash_type} "${hash}" ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2 2>&1)
538
539 ret=${?}
540
541 echo "${output}" >> ${OUTD}/logfull.txt
542
543 if [ "${ret}" -eq 0 ]; then
544
545 line_nr=$((i - 1))
546
547 line_dict1=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict1)
548 line_dict2=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict2)
549
550 if [ ${pass_only} -eq 1 ]; then
551 search=":${line_dict1}${line_dict2}"
552 else
553 search="${hash}:${line_dict1}${line_dict2}"
554 fi
555
556 echo "${output}" | grep -F "${search}" &> /dev/null
557
558 if [ "${?}" -ne 0 ]; then
559
560 ret=10
561
562 fi
563
564 fi
565
566 status ${ret}
567
568 fi
569
570 ((i++))
571
572 done 9< ${OUTD}/${hash_type}_hashes.txt
573
574 msg="OK"
575
576 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
577
578 msg="Error"
579
580 elif [ "${e_to}" -ne 0 ]; then
581
582 msg="Warning"
583
584 fi
585
586 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 1, Mode single, Device-Type ${TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
587
588 fi
589
590 # multihash
591 if [ ${MODE} -ne 0 ]; then
592
593 e_to=0
594 e_nf=0
595 e_nm=0
596 cnt=0
597
598 offset=14
599
600 if [ ${hash_type} -eq 2500 ]; then
601 offset=7
602 elif [ ${hash_type} -eq 5800 ]; then
603 offset=6
604 elif [ ${hash_type} -eq 3000 ]; then
605 offset=6
606 elif [ ${hash_type} -eq 2100 ]; then
607 offset=11
608 elif [ ${hash_type} -eq 1500 ]; then
609 offset=7
610 elif [ ${hash_type} -eq 7700 ]; then
611 offset=7
612 elif [ ${hash_type} -eq 8500 ]; then
613 offset=7
614 fi
615
616 hash_file=${OUTD}/${hash_type}_multihash_combi.txt
617
618 tail -n ${offset} ${OUTD}/${hash_type}_hashes.txt > ${hash_file}
619
620 # if file_only -> decode all base64 "hashes" and put them in the temporary file
621
622 if [ "${file_only}" -eq 1 ]; then
623
624 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
625 rm -f ${temp_file}
626
627 hash_file=${temp_file}
628
629 while read base64_hash; do
630
631 echo -n ${base64_hash} | base64 -d >> ${temp_file}
632
633 done < ${OUTD}/${hash_type}_multihash_combi.txt
634
635 fi
636
637 CMD="./${BIN} ${OPTS} -a 1 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2"
638
639 echo "> Testing hash type $hash_type with attack mode 1, markov ${MARKOV}, multi hash, Device-Type ${TYPE}, vector-width ${VECTOR}." &>> ${OUTD}/logfull.txt
640
641 output=$(./${BIN} ${OPTS} -a 1 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2 2>&1)
642
643 ret=${?}
644
645 echo "${output}" >> ${OUTD}/logfull.txt
646
647 if [ "${ret}" -eq 0 ]; then
648
649 i=0
650
651 while read -u 9 hash; do
652
653 line_nr=$((offset - i))
654
655 line_dict1=$(tail -n ${line_nr} ${OUTD}/${hash_type}_dict1 | head -1)
656 line_dict2=$(tail -n ${line_nr} ${OUTD}/${hash_type}_dict2 | head -1)
657
658 if [ ${pass_only} -eq 1 ]; then
659 search=":${line_dict1}${line_dict2}"
660 else
661 search="${hash}:${line_dict1}${line_dict2}"
662 fi
663
664 echo "${output}" | grep -F "${search}" &> /dev/null
665
666 if [ "${?}" -ne 0 ]; then
667
668 ret=10
669
670 break
671
672 fi
673
674 i=$((i + 1))
675
676 done 9< ${OUTD}/${hash_type}_multihash_combi.txt
677
678 fi
679
680 status ${ret}
681
682 msg="OK"
683
684 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
685
686 msg="Error"
687
688 elif [ "${e_to}" -ne 0 ]; then
689
690 msg="Warning"
691
692 fi
693
694 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 1, Mode multi, Device-Type ${TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
695
696 fi
697 }
698
699 function attack_3()
700 {
701 file_only=0
702
703 if ! contains ${hash_type} ${FILE_BASED_ALGOS}; then
704
705 file_only=1
706
707 fi
708
709 # single hash
710 if [ ${MODE} -ne 1 ]; then
711
712 e_to=0
713 e_nf=0
714 e_nm=0
715 cnt=0
716
717 echo "> Testing hash type $hash_type with attack mode 3, markov ${MARKOV}, single hash, Device-Type ${TYPE}, vector-width ${VECTOR}." &>> ${OUTD}/logfull.txt
718
719 max=8
720 mask_offset=0
721
722 # some algos have a minimum password length
723
724 if [ "${hash_type}" -eq 2500 ];then
725
726 mask_offset=7
727 max=7
728
729 fi
730
731 i=1
732
733 while read -u 9 hash; do
734
735 if [ "${i}" -gt 6 ]; then
736
737 if ! contains ${hash_type} ${TIMEOUT_ALGOS}; then
738
739 break;
740
741 fi
742
743 fi
744
745 if [ "${file_only}" -eq 1 ]; then
746
747 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
748 echo ${hash} | base64 -d > ${temp_file}
749 hash="${temp_file}"
750
751 fi
752
753 mask=${mask_3[$((i + ${mask_offset}))]}
754
755 # modify "default" mask if needed (and set custom charset to reduce keyspace)
756
757 if [ "${hash_type}" -eq 2500 ]; then
758
759 pass=$(sed -n ${i}p ${OUTD}/${hash_type}_passwords.txt)
760
761 mask=${pass}
762
763 # replace the first x positions in the mask with ?d's
764
765 # first: remove first i (== amount) chars
766
767 mask=$(echo ${mask} | cut -b $((i + 1))-)
768
769 # prepend the ?d's
770
771 for i in $(seq 1 ${i}); do
772
773 mask="?d${mask}"
774
775 done
776
777 fi
778
779 CMD="./${BIN} ${OPTS} -a 3 -m ${hash_type} '${hash}' ${mask}"
780
781 echo -n "[ len $i ] " &>> ${OUTD}/logfull.txt
782
783 output=$(./${BIN} ${OPTS} -a 3 -m ${hash_type} "${hash}" ${mask} 2>&1)
784
785 ret=${?}
786
787 echo "${output}" >> ${OUTD}/logfull.txt
788
789 if [ "${ret}" -eq 0 ]; then
790
791 line_dict=$(sed -n ${i}p ${OUTD}/${hash_type}_passwords.txt)
792
793 if [ ${pass_only} -eq 1 ]; then
794 search=":${line_dict}"
795 else
796 search="${hash}:${line_dict}"
797 fi
798
799 echo "${output}" | grep -F "${search}" &> /dev/null
800
801 if [ "${?}" -ne 0 ]; then
802
803 ret=10
804
805 fi
806
807 fi
808
809 status ${ret}
810
811 if [ $i -eq ${max} ]; then break; fi
812
813 ((i++))
814
815 done 9< ${OUTD}/${hash_type}_hashes.txt
816
817 msg="OK"
818
819 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
820
821 msg="Error"
822
823 elif [ "${e_to}" -ne 0 ]; then
824
825 msg="Warning"
826
827 fi
828
829 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 3, Mode single, Device-Type ${TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
830
831 fi
832
833 # multihash
834 if [ ${MODE} -ne 0 ]; then
835
836 e_to=0
837 e_nf=0
838 e_nm=0
839 cnt=0
840
841 increment_max=8
842
843 if ! contains ${hash_type} ${TIMEOUT_ALGOS}; then
844
845 increment_max=5
846
847 fi
848
849 increment_min=1
850
851 if [ "${hash_type}" -eq 2500 ]; then
852
853 increment_min=8
854 increment_max=9
855
856 fi
857
858 hash_file=${OUTD}/${hash_type}_multihash_bruteforce.txt
859
860 head -n $((increment_max - ${increment_min} + 1)) ${OUTD}/${hash_type}_hashes.txt > ${hash_file}
861
862 # if file_only -> decode all base64 "hashes" and put them in the temporary file
863
864 if [ "${file_only}" -eq 1 ]; then
865
866 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
867 rm -f ${temp_file}
868
869 hash_file=${temp_file}
870
871 while read base64_hash; do
872
873 echo -n ${base64_hash} | base64 -d >> ${temp_file}
874
875 done < ${OUTD}/${hash_type}_multihash_bruteforce.txt
876
877 fi
878
879 mask=${mask_3[8]}
880 custom_charsets=""
881
882 # modify "default" mask if needed (and set custom charset to reduce keyspace)
883
884 if [ "${hash_type}" -eq 2500 ]; then
885
886 mask="?d?d?d?d?d?1?2?3?4"
887
888 charset_1=""
889 charset_2=""
890 charset_3=""
891 charset_4=""
892
893 # check positions (here we assume that mask is always composed of non literal chars
894 # i.e. something like ?d?l?u?s?1 is possible, but ?d?dsuffix not
895 charset_1_pos=$(expr index "${mask}" 1)
896 charset_2_pos=$(expr index "${mask}" 2)
897 charset_3_pos=$(expr index "${mask}" 3)
898 charset_4_pos=$(expr index "${mask}" 4)
899
900 # divide each charset position by 2 since each of them occupies 2 positions in the mask
901
902 charset_1_pos=$((charset_1_pos / 2))
903 charset_2_pos=$((charset_2_pos / 2))
904 charset_3_pos=$((charset_3_pos / 2))
905 charset_4_pos=$((charset_4_pos / 2))
906
907 i=1
908
909 while read -u 9 hash; do
910
911 pass=$(sed -n ${i}p ${OUTD}/${hash_type}_passwords.txt)
912
913 # charset 1
914 char=$(echo "${pass}" | cut -b ${charset_1_pos})
915 charset_1=$(echo -e "${charset_1}\n${char}")
916
917 # charset 2
918 char=$(echo "${pass}" | cut -b ${charset_2_pos})
919 charset_2=$(echo -e "${charset_2}\n${char}")
920
921 # charset 3
922 char=$(echo "${pass}" | cut -b ${charset_3_pos})
923 charset_3=$(echo -e "${charset_3}\n${char}")
924
925 # charset 4
926 char=$(echo "${pass}" | cut -b ${charset_4_pos})
927 charset_4=$(echo -e "${charset_4}\n${char}")
928
929 i=$((i + 1))
930
931 done 9< ${OUTD}/${hash_type}_multihash_bruteforce.txt
932
933 # just make sure that all custom charset fields are initialized
934
935 if [ -z "${charset_1}" ]; then
936
937 charset_1="1"
938
939 fi
940
941 if [ -z "${charset_2}" ]; then
942
943 charset_2="2"
944
945 fi
946
947 if [ -z "${charset_3}" ]; then
948
949 charset_3="3"
950
951 fi
952
953 if [ -z "${charset_4}" ]; then
954
955 charset_4="4"
956
957 fi
958
959 # unique and remove new lines
960
961 charset_1=$(echo "${charset_1}" | sort -u | tr -d '\n')
962 charset_2=$(echo "${charset_2}" | sort -u | tr -d '\n')
963 charset_3=$(echo "${charset_3}" | sort -u | tr -d '\n')
964 charset_4=$(echo "${charset_4}" | sort -u | tr -d '\n')
965
966 custom_charsets="-1 ${charset_1} -2 ${charset_2} -3 ${charset_3} -4 ${charset_4}"
967 fi
968
969 CMD="./${BIN} ${OPTS} -a 3 -m ${hash_type} --increment --increment-min ${increment_min} --increment-max ${increment_max} ${custom_charsets} ${hash_file} ${mask} "
970
971 echo "> Testing hash type $hash_type with attack mode 3, markov ${MARKOV}, multi hash, Device-Type ${TYPE}, vector-width ${VECTOR}." &>> ${OUTD}/logfull.txt
972
973 output=$(./${BIN} ${OPTS} -a 3 -m ${hash_type} --increment --increment-min ${increment_min} --increment-max ${increment_max} ${custom_charsets} ${hash_file} ${mask} 2>&1)
974
975 ret=${?}
976
977 echo "${output}" >> ${OUTD}/logfull.txt
978
979 if [ "${ret}" -eq 0 ]; then
980
981 i=1
982
983 while read -u 9 hash; do
984
985 pass=$(sed -n ${i}p ${OUTD}/${hash_type}_passwords.txt)
986
987 if [ ${pass_only} -eq 1 ]; then
988 search=":${pass}"
989 else
990 search="${hash}:${pass}"
991 fi
992
993 echo "${output}" | grep -F "${search}" &> /dev/null
994
995 if [ "${?}" -ne 0 ]; then
996
997 ret=10
998
999 break
1000
1001 fi
1002
1003 i=$((i + 1))
1004
1005 done 9< ${OUTD}/${hash_type}_multihash_bruteforce.txt
1006
1007 fi
1008
1009 status ${ret}
1010
1011 msg="OK"
1012
1013 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
1014
1015 msg="Error"
1016
1017 elif [ "${e_to}" -ne 0 ]; then
1018
1019 msg="Warning"
1020
1021 fi
1022
1023 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 3, Mode multi, Device-Type ${TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
1024
1025 fi
1026 }
1027
1028 function attack_6()
1029 {
1030 file_only=0
1031
1032 if ! contains ${hash_type} ${FILE_BASED_ALGOS}; then
1033
1034 file_only=1
1035
1036 fi
1037
1038 # single hash
1039 if [ ${MODE} -ne 1 ]; then
1040
1041 e_to=0
1042 e_nf=0
1043 e_nm=0
1044 cnt=0
1045
1046 echo "> Testing hash type $hash_type with attack mode 6, markov ${MARKOV}, single hash, Device-Type ${TYPE}, vector-width ${VECTOR}." &>> ${OUTD}/logfull.txt
1047
1048 i=1
1049
1050 max=8
1051
1052 if [ "${hash_type}" -eq 2500 ]; then
1053
1054 max=6
1055
1056 fi
1057
1058 while read -u 9 hash; do
1059
1060 if [ "${i}" -gt 6 ]; then
1061
1062 if ! contains ${hash_type} ${TIMEOUT_ALGOS}; then
1063
1064 break;
1065
1066 fi
1067
1068 fi
1069
1070 if [ $i -gt 1 ]; then
1071
1072 if [ "${file_only}" -eq 1 ]; then
1073
1074 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
1075 echo ${hash} | base64 -d > ${temp_file}
1076 hash="${temp_file}"
1077
1078 fi
1079
1080 CMD="./${BIN} ${OPTS} -a 6 -m ${hash_type} '${hash}' ${OUTD}/${hash_type}_dict1 ${mask_6[$i]}"
1081
1082 echo -n "[ len $i ] " &>> ${OUTD}/logfull.txt
1083
1084 output=$(./${BIN} ${OPTS} -a 6 -m ${hash_type} "${hash}" ${OUTD}/${hash_type}_dict1 ${mask_6[$i]} 2>&1)
1085
1086 ret=${?}
1087
1088 echo "${output}" >> ${OUTD}/logfull.txt
1089
1090 if [ "${ret}" -eq 0 ]; then
1091
1092 line_nr=$((i - 1))
1093
1094 line_dict1=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict1)
1095 line_dict2=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict2)
1096
1097 if [ ${pass_only} -eq 1 ]; then
1098 search=":${line_dict1}${line_dict2}"
1099 else
1100 search="${hash}:${line_dict1}${line_dict2}"
1101 fi
1102
1103 echo "${output}" | grep -F "${search}" &> /dev/null
1104
1105 if [ "${?}" -ne 0 ]; then
1106
1107 ret=10
1108
1109 fi
1110
1111 fi
1112
1113 status ${ret}
1114
1115 fi
1116
1117 if [ "${i}" -eq ${max} ]; then break; fi
1118
1119 ((i++))
1120
1121 done 9< ${OUTD}/${hash_type}_hashes.txt
1122
1123 msg="OK"
1124
1125 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
1126
1127 msg="Error"
1128
1129 elif [ "${e_to}" -ne 0 ]; then
1130
1131 msg="Warning"
1132
1133 fi
1134
1135 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 6, Mode single, Device-Type ${TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
1136
1137 fi
1138
1139 # multihash
1140 if [ ${MODE} -ne 0 ]; then
1141
1142 e_to=0
1143 e_nf=0
1144 e_nm=0
1145 cnt=0
1146
1147 max=9
1148
1149 if [ ${hash_type} -eq 2500 ]; then
1150 max=5
1151 elif [ ${hash_type} -eq 3000 ]; then
1152 max=8
1153 elif [ ${hash_type} -eq 7700 ]; then
1154 max=8
1155 elif [ ${hash_type} -eq 8500 ]; then
1156 max=8
1157 fi
1158
1159 if ! contains ${hash_type} ${TIMEOUT_ALGOS}; then
1160
1161 max=5
1162
1163 if [ "${hash_type}" -eq 3200 ]; then
1164
1165 max=3
1166
1167 fi
1168
1169 fi
1170
1171 for ((i = 2; i < ${max}; i++)); do
1172
1173 hash_file=${OUTD}/${hash_type}_hashes_multi_${i}.txt
1174
1175 # if file_only -> decode all base64 "hashes" and put them in the temporary file
1176
1177 if [ "${file_only}" -eq 1 ]; then
1178
1179 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
1180 rm -f ${temp_file}
1181
1182 hash_file=${temp_file}
1183
1184 while read base64_hash; do
1185
1186 echo -n ${base64_hash} | base64 -d >> ${temp_file}
1187
1188 done < ${OUTD}/${hash_type}_hashes_multi_${i}.txt
1189
1190 fi
1191
1192 CMD="./${BIN} ${OPTS} -a 6 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1_multi_${i} ${mask_6[$i]}"
1193
1194 echo "> Testing hash type $hash_type with attack mode 6, markov ${MARKOV}, multi hash with word len ${i}." &>> ${OUTD}/logfull.txt
1195
1196 output=$(./${BIN} ${OPTS} -a 6 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1_multi_${i} ${mask_6[$i]} 2>&1)
1197
1198 ret=${?}
1199
1200 echo "${output}" >> ${OUTD}/logfull.txt
1201
1202 if [ "${ret}" -eq 0 ]; then
1203
1204 j=1
1205
1206 while read -u 9 hash; do
1207
1208 line_dict1=$(sed -n ${j}p ${OUTD}/${hash_type}_dict1_multi_${i})
1209 line_dict2=$(sed -n ${j}p ${OUTD}/${hash_type}_dict2_multi_${i})
1210
1211 if [ ${pass_only} -eq 1 ]; then
1212 search=":${line_dict1}${line_dict2}"
1213 else
1214 search="${hash}:${line_dict1}${line_dict2}"
1215 fi
1216
1217 echo "${output}" | grep -F "${search}" &> /dev/null
1218
1219 if [ "${?}" -ne 0 ]; then
1220
1221 ret=10
1222
1223 break
1224
1225 fi
1226
1227 j=$((j + 1))
1228
1229 done 9< ${OUTD}/${hash_type}_hashes_multi_${i}.txt
1230
1231 fi
1232
1233 status ${ret}
1234
1235 done
1236
1237 msg="OK"
1238
1239 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
1240
1241 msg="Error"
1242
1243 elif [ "${e_to}" -ne 0 ]; then
1244
1245 msg="Warning"
1246
1247 fi
1248
1249 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 6, Mode multi, Device-Type ${TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
1250
1251 fi
1252 }
1253
1254 function attack_7()
1255 {
1256 file_only=0
1257
1258 if ! contains ${hash_type} ${FILE_BASED_ALGOS}; then
1259
1260 file_only=1
1261
1262 fi
1263
1264 # single hash
1265 if [ ${MODE} -ne 1 ]; then
1266
1267 e_to=0
1268 e_nf=0
1269 e_nm=0
1270 cnt=0
1271
1272 echo "> Testing hash type $hash_type with attack mode 7, markov ${MARKOV}, single hash, Device-Type ${TYPE}, vector-width ${VECTOR}." &>> ${OUTD}/logfull.txt
1273
1274 max=8
1275
1276 if [ "${hash_type}" -eq 2500 ]; then
1277
1278 max=5
1279
1280 fi
1281
1282 i=1
1283
1284 while read -u 9 hash; do
1285
1286 if [ $i -gt 1 ]; then
1287
1288 if [ "${file_only}" -eq 1 ]; then
1289
1290 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
1291 echo ${hash} | base64 -d > ${temp_file}
1292 hash="${temp_file}"
1293
1294 fi
1295
1296 mask=${mask_7[$i]}
1297
1298 # adjust mask if needed
1299
1300 if [ "${hash_type}" -eq 2500 ]; then
1301
1302 line_nr=$((i - 1))
1303
1304 pass_part_1=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict1)
1305 pass_part_2=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict2)
1306
1307 pass_part_2_len=${#pass_part_2}
1308
1309 pass=${pass_part_1}${pass_part_2}
1310 pass_len=${#pass}
1311
1312 # add first x chars of password to mask and append the (old) mask
1313
1314 mask_len=${#mask}
1315 mask_len=$((mask_len / 2))
1316
1317 mask_prefix=$(echo ${pass} | cut -b -$((pass_len - ${mask_len} - ${pass_part_2_len})))
1318 mask=${mask_prefix}${mask}
1319
1320 fi
1321
1322 CMD="./${BIN} ${OPTS} -a 7 -m ${hash_type} '${hash}' ${mask} ${OUTD}/${hash_type}_dict2"
1323
1324 echo -n "[ len $i ] " &>> ${OUTD}/logfull.txt
1325
1326 output=$(./${BIN} ${OPTS} -a 7 -m ${hash_type} "${hash}" ${mask} ${OUTD}/${hash_type}_dict2 2>&1)
1327
1328 ret=${?}
1329
1330 echo "${output}" >> ${OUTD}/logfull.txt
1331
1332 if [ "${ret}" -eq 0 ]; then
1333
1334 line_nr=$((i - 1))
1335
1336 line_dict1=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict1)
1337 line_dict2=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict2)
1338
1339 if [ ${pass_only} -eq 1 ]; then
1340 search=":${line_dict1}${line_dict2}"
1341 else
1342 search="${hash}:${line_dict1}${line_dict2}"
1343 fi
1344
1345 echo "${output}" | grep -F "${search}" &> /dev/null
1346
1347 if [ "${?}" -ne 0 ]; then
1348
1349 ret=10
1350
1351 fi
1352
1353 fi
1354
1355 status ${ret}
1356
1357 fi
1358
1359 if [ $i -eq ${max} ]; then break; fi
1360
1361 ((i++))
1362
1363 done 9< ${OUTD}/${hash_type}_hashes.txt
1364
1365 msg="OK"
1366
1367 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
1368
1369 msg="Error"
1370
1371 elif [ "${e_to}" -ne 0 ]; then
1372
1373 msg="Warning"
1374
1375 fi
1376
1377 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 7, Mode single, Device-Type ${TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
1378
1379 fi
1380
1381 # multihash
1382 if [ ${MODE} -ne 0 ]; then
1383
1384 e_to=0
1385 e_nf=0
1386 e_nm=0
1387 cnt=0
1388
1389 max=9
1390
1391 if [ ${hash_type} -eq 2500 ]; then
1392 max=5
1393 elif [ ${hash_type} -eq 3000 ]; then
1394 max=8
1395 elif [ ${hash_type} -eq 7700 ]; then
1396 max=8
1397 elif [ ${hash_type} -eq 8500 ]; then
1398 max=8
1399 fi
1400
1401 if ! contains ${hash_type} ${TIMEOUT_ALGOS}; then
1402
1403 max=7
1404
1405 if [ "${hash_type}" -eq 3200 ]; then
1406
1407 max=4
1408
1409 fi
1410
1411 fi
1412
1413 for ((i = 2; i < ${max}; i++)); do
1414
1415 hash_file=${OUTD}/${hash_type}_hashes_multi_${i}.txt
1416 dict_file=${OUTD}/${hash_type}_dict2_multi_${i}
1417
1418 mask=${mask_7[$i]}
1419
1420 # if file_only -> decode all base64 "hashes" and put them in the temporary file
1421
1422 if [ "${file_only}" -eq 1 ]; then
1423
1424 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
1425 rm -f ${temp_file}
1426
1427 hash_file=${temp_file}
1428
1429 while read base64_hash; do
1430
1431 echo -n ${base64_hash} | base64 -d >> ${temp_file}
1432
1433 done < ${OUTD}/${hash_type}_hashes_multi_${i}.txt
1434
1435 # a little hack: since we don't want to have a very large mask (and wpa has minimum length of 8),
1436 # we need to create a temporary dict file on-the-fly and use it like this: [small mask] [long(er) words in dict]
1437
1438 dict_file=${OUTD}/${hash_type}_dict2_multi_${i}_longer
1439 rm -f ${dict_file}
1440
1441 mask_len=${#mask}
1442 mask_len=$((mask_len / 2))
1443
1444 j=1
1445
1446 while read -u 9 hash; do
1447
1448 pass_part_1=$(sed -n ${j}p ${OUTD}/${hash_type}_dict1_multi_${i})
1449 pass_part_2=$(sed -n ${j}p ${OUTD}/${hash_type}_dict2_multi_${i})
1450
1451 pass="${pass_part_1}${pass_part_2}"
1452
1453 pass_suffix=$(echo "${pass}" | cut -b $((mask_len + 1))-)
1454
1455 echo "${pass_suffix}" >> ${dict_file}
1456
1457 j=$((j + 1))
1458
1459 done 9< ${OUTD}/${hash_type}_hashes_multi_${i}.txt
1460
1461 fi
1462
1463 CMD="./${BIN} ${OPTS} -a 7 -m ${hash_type} ${hash_file} ${mask} ${dict_file}"
1464
1465 echo "> Testing hash type $hash_type with attack mode 7, markov ${MARKOV}, multi hash with word len ${i}." &>> ${OUTD}/logfull.txt
1466
1467 output=$(./${BIN} ${OPTS} -a 7 -m ${hash_type} ${hash_file} ${mask} ${dict_file} 2>&1)
1468
1469 ret=${?}
1470
1471 echo "${output}" >> ${OUTD}/logfull.txt
1472
1473 if [ "${ret}" -eq 0 ]; then
1474
1475 j=1
1476
1477 while read -u 9 hash; do
1478
1479 line_dict1=$(sed -n ${j}p ${OUTD}/${hash_type}_dict1_multi_${i})
1480 line_dict2=$(sed -n ${j}p ${OUTD}/${hash_type}_dict2_multi_${i})
1481
1482 if [ ${pass_only} -eq 1 ]; then
1483 search=":${line_dict1}${line_dict2}"
1484 else
1485 search="${hash}:${line_dict1}${line_dict2}"
1486 fi
1487
1488 echo "${output}" | grep -F "${search}" &> /dev/null
1489
1490 if [ "${?}" -ne 0 ]; then
1491
1492 ret=10
1493
1494 break
1495
1496 fi
1497
1498 j=$((j + 1))
1499
1500 done 9< ${OUTD}/${hash_type}_hashes_multi_${i}.txt
1501
1502 fi
1503
1504 status ${ret}
1505
1506 done
1507
1508 msg="OK"
1509
1510 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
1511
1512 msg="Error"
1513
1514 elif [ "${e_to}" -ne 0 ]; then
1515
1516 msg="Warning"
1517
1518 fi
1519
1520 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 7, Mode multi, Device-Type ${TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
1521
1522 fi
1523 }
1524
1525 function usage()
1526 {
1527 cat << EOF
1528 > Usage : ${0} <options>
1529
1530 OPTIONS:
1531
1532 -V OpenCL vector-width (either 1, 2, 4 or 8), overrides value from device query :
1533 '1' => vector-width 1
1534 '2' => vector-width 2 (default)
1535 '4' => vector-width 4
1536 '8' => vector-width 8
1537 'all' => test sequentially vector-width ${VECTOR_WIDTHS}
1538
1539 -T OpenCL device-types to use :
1540 'gpu' => gpu devices (default)
1541 'cpu' => cpu devices
1542 'all' => gpu and cpu devices
1543
1544 -t Select test mode :
1545 'single' => single hash (default)
1546 'multi' => multi hash
1547 'all' => single and multi hash
1548
1549 -m Select hash type :
1550 'all' => all hash type supported
1551 (int) => hash type integer code (default : 0)
1552
1553 -a Select attack mode :
1554 'all' => all attack modes
1555 (int) => attack mode integer code (default : 0)
1556
1557 -x Select cpu architecture :
1558 '32' => 32 bit architecture
1559 '64' => 64 bit architecture (default)
1560
1561 -o Select operating system :
1562 'win' => windows operating system (use .exe file extension etc)
1563 'linux' => *nix based operating systems (.bin for binaries)
1564 'osx' => mac osx operating systems (.app for binaries)
1565
1566 -c Disables markov-chains
1567
1568 -p Package the tests into a .7z file
1569
1570 -d Use this folder as input/output folder for packaged tests
1571 (string) => path to folder
1572
1573 -h Show this help
1574
1575 EOF
1576
1577 exit 1
1578 }
1579
1580 BIN="oclHashcat"
1581 MARKOV="enabled"
1582 ATTACK=0
1583 MODE=0
1584 TYPE="null"
1585 VECTOR="default"
1586 HT=0
1587 PACKAGE=0
1588
1589 while getopts "V:T:t:m:a:b:hcpd:x:o:" opt; do
1590
1591 case ${opt} in
1592 "V")
1593 if [ ${OPTARG} == "1" ]; then
1594 VECTOR=1
1595 elif [ ${OPTARG} == "2" ]; then
1596 VECTOR=2
1597 elif [ ${OPTARG} == "4" ]; then
1598 VECTOR=4
1599 elif [ ${OPTARG} == "8" ]; then
1600 VECTOR=8
1601 elif [ ${OPTARG} == "all" ]; then
1602 VECTOR="all"
1603 else
1604 usage
1605 fi
1606 ;;
1607
1608 "T")
1609 if [ ${OPTARG} == "gpu" ]; then
1610 OPTS="${OPTS} --opencl-device-types 2"
1611 TYPE="Gpu"
1612 elif [ ${OPTARG} == "cpu" ]; then
1613 OPTS="${OPTS} --opencl-device-types 1"
1614 TYPE="Cpu"
1615 elif [ ${OPTARG} == "all" ]; then
1616 OPTS="${OPTS} --opencl-device-types 1,2"
1617 TYPE="Cpu + Gpu"
1618 else
1619 usage
1620 fi
1621 ;;
1622
1623 "t")
1624 if [ ${OPTARG} == "single" ]; then
1625 MODE=0
1626 elif [ ${OPTARG} == "multi" ]; then
1627 MODE=1
1628 elif [ ${OPTARG} == "all" ]; then
1629 MODE=2
1630 else
1631 usage
1632 fi
1633 ;;
1634
1635 "m")
1636 if [ ${OPTARG} == "all" ]; then
1637 HT=65535
1638 else
1639 HT=${OPTARG}
1640 fi
1641 ;;
1642
1643 "a")
1644 if [ ${OPTARG} == "all" ]; then
1645 ATTACK=65535
1646 elif [ ${OPTARG} == "0" ]; then
1647 ATTACK=0
1648 elif [ ${OPTARG} == "1" ]; then
1649 ATTACK=1
1650 elif [ ${OPTARG} == "3" ]; then
1651 ATTACK=3
1652 elif [ ${OPTARG} == "6" ]; then
1653 ATTACK=6
1654 elif [ ${OPTARG} == "7" ]; then
1655 ATTACK=7
1656 else
1657 usage
1658 fi
1659 ;;
1660
1661 "c")
1662 OPTS="${OPTS} --markov-disable"
1663 MARKOV="disabled"
1664 ;;
1665
1666 "d")
1667 PACKAGE_FOLDER=$( echo ${OPTARG} | sed 's!/$!!g' )
1668 ;;
1669
1670 "p")
1671 PACKAGE=1
1672 ;;
1673
1674 "x")
1675 if [ ${OPTARG} == "32" ]; then
1676 ARCHITECTURE=32
1677 elif [ ${OPTARG} == "64" ]; then
1678 ARCHITECTURE=64
1679 else
1680 usage
1681 fi
1682 ;;
1683
1684 "o")
1685 if [ ${OPTARG} == "win" ]; then
1686 EXTENSION="exe"
1687 elif [ ${OPTARG} == "linux" ]; then
1688 EXTENSION="bin"
1689 elif [ ${OPTARG} == "osx" ]; then
1690 EXTENSION="app"
1691 else
1692 usage
1693 fi
1694 ;;
1695
1696 \?)
1697 usage
1698 ;;
1699
1700 "h")
1701 usage
1702 ;;
1703 esac
1704
1705 done
1706
1707 if [ "${TYPE}" == "null" ]; then
1708 TYPE="Gpu"
1709 OPTS="${OPTS} --opencl-device-types 2"
1710 fi
1711
1712 if [ -n "${ARCHITECTURE}" ]; then
1713
1714 BIN="${BIN}${ARCHITECTURE}"
1715
1716 fi
1717
1718 if [ -n "${EXTENSION}" ]; then
1719
1720 BIN="${BIN}.${EXTENSION}"
1721
1722 fi
1723
1724 if [ -n "${PACKAGE_FOLDER}" ]; then
1725
1726 if [ ! -e "${PACKAGE_FOLDER}" ]; then
1727 echo "! folder '${PACKAGE_FOLDER}' does not exist"
1728 exit 1
1729 fi
1730
1731 fi
1732
1733 if [ "${PACKAGE}" -eq 0 -o -z "${PACKAGE_FOLDER}" ]; then
1734
1735 # check existence of binary
1736 if [ ! -e "${BIN}" ]; then
1737 echo "! ${BIN} not found, please build binary before run test."
1738 exit 1
1739 fi
1740
1741 # filter by hash_type
1742 if [ ${HT} -ne 65535 ]; then
1743
1744 # validate filter
1745 check=0
1746 for hash_type in $(echo ${HASH_TYPES}); do
1747
1748 if [ ${HT} -ne ${hash_type} ]; then continue; fi
1749
1750 check=1
1751
1752 break
1753
1754 done
1755
1756 if [ ${check} -ne 1 ]; then
1757 echo "! invalid hash type selected ..."
1758 usage
1759 fi
1760
1761 fi
1762
1763 if [ -z "${PACKAGE_FOLDER}" ]; then
1764
1765 # make new dir
1766 mkdir -p ${OUTD}
1767
1768 # generate random test entry
1769 if [ ${HT} -eq 65535 ]; then
1770 perl tools/test.pl single > ${OUTD}/all.sh
1771 else
1772 perl tools/test.pl single ${HT} > ${OUTD}/all.sh
1773 fi
1774
1775 else
1776
1777 OUTD=${PACKAGE_FOLDER}
1778
1779 fi
1780
1781 rm -rf ${OUTD}/logfull.txt && touch ${OUTD}/logfull.txt
1782
1783 # populate array of hash types where we only should check if pass is in output (not both hash:pass)
1784 IFS=';' read -ra PASS_ONLY <<< "${MATCH_PASS_ONLY}"
1785 IFS=';' read -ra TIMEOUT_ALGOS <<< "${SLOW_ALGOS}"
1786
1787 IFS=';' read -ra NEVER_CRACK_ALGOS <<< "${NEVER_CRACK}"
1788
1789 # for these particular algos we need to save the output to a temporary file
1790 IFS=';' read -ra FILE_BASED_ALGOS <<< "${HASHFILE_ONLY}"
1791
1792 for hash_type in $(echo $HASH_TYPES); do
1793
1794 if [[ ${HT} -ne 65535 ]] && [[ ${HT} -ne ${hash_type} ]]; then continue; fi
1795
1796 if [ -z "${PACKAGE_FOLDER}" ]; then
1797
1798 # init test data
1799 init
1800
1801 else
1802
1803 echo "[ ${OUTD} ] > Run packaged test for hash type $hash_type."
1804
1805 fi
1806
1807 if [ "${PACKAGE}" -eq 0 ]; then
1808
1809 # should we check only the pass?
1810 contains ${hash_type} ${PASS_ONLY}
1811 pass_only=$?
1812
1813 contains ${hash_type} ${SLOW_ALGOS}
1814 IS_SLOW=$?
1815
1816 if [[ ${hash_type} -eq 400 ]]; then
1817 # we use phpass as slow hash for testing the AMP kernel
1818 IS_SLOW=0
1819 fi
1820
1821 OPTS_OLD=${OPTS}
1822 VECTOR_OLD=${VECTOR}
1823 for CUR_WIDTH in $(echo $VECTOR_WIDTHS); do
1824
1825 if [ "${VECTOR_OLD}" == "all" ] || [ "${VECTOR_OLD}" == "default" ] || [ "${VECTOR_OLD}" == "${CUR_WIDTH}" ]; then
1826
1827 if [ "${VECTOR_OLD}" == "default" ] && \
1828 [ "${CUR_WIDTH}" != "1" ] && \
1829 [ "${CUR_WIDTH}" != "4" ]; then
1830
1831 continue
1832 fi
1833
1834 VECTOR=${CUR_WIDTH}
1835 OPTS="${OPTS_OLD} --opencl-vector-width ${VECTOR}"
1836
1837 if [[ ${IS_SLOW} -eq 1 ]]; then
1838
1839 # run attack mode 0 (stdin)
1840 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 0 ]]; then attack_0; fi
1841
1842 else
1843
1844 # run attack mode 0 (stdin)
1845 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 0 ]]; then attack_0; fi
1846
1847 # run attack mode 1 (combinator)
1848 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 1 ]]; then attack_1; fi
1849
1850 # run attack mode 3 (bruteforce)
1851 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 3 ]]; then attack_3; fi
1852
1853 # run attack mode 6 (dict+mask)
1854 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 6 ]]; then attack_6; fi
1855
1856 # run attack mode 7 (mask+dict)
1857 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 7 ]]; then attack_7; fi
1858
1859 fi
1860 fi
1861 done
1862 OPTS="${OPTS_OLD}"
1863 VECTOR="${VECTOR_OLD}"
1864 fi
1865 done
1866
1867 else
1868
1869 OUTD=${PACKAGE_FOLDER}
1870
1871 fi
1872
1873 # fix logfile
1874 if [ "${PACKAGE}" -eq 0 ]; then
1875
1876 cat -A ${OUTD}/logfull.txt | sed -e 's/\^M \^M//g' | sed -e 's/\$$//g' > ${OUTD}/test_report.log
1877
1878 fi
1879
1880 rm -rf ${OUTD}/logfull.txt
1881
1882 if [ "${PACKAGE}" -eq 1 ]; then
1883
1884 echo "[ ${OUTD} ] > Generate package ${OUTD}/${OUTD}.7z"
1885
1886 cp "${BASH_SOURCE[0]}" ${OUTD}/test.sh
1887
1888 # if we package from a given folder, we need to check if e.g. the files needed for multi mode are there
1889
1890 if [ -n "${PACKAGE_FOLDER}" ]; then
1891
1892 MODE=2
1893
1894 ls "${PACKAGE_FOLDER}"/*multi* &> /dev/null
1895
1896 if [ "${?}" -ne 0 ]
1897 then
1898
1899 MODE=0
1900
1901 fi
1902
1903 HT=$(grep -o -- "-m *[0-9]*" ${PACKAGE_FOLDER}/all.sh | sort -u | sed 's/-m //' 2> /dev/null)
1904
1905 if [ -n "${HT}" ]; then
1906
1907 HT_COUNT=$(echo "${HT}" | wc -l)
1908
1909 if [ "${HT_COUNT}" -gt 1 ]; then
1910
1911 HT=65535
1912
1913 fi
1914
1915 fi
1916
1917 #ATTACK=65535 # more appropriate ?
1918 fi
1919
1920 # for convenience: 'run package' is default action for packaged test.sh ( + add other defaults too )
1921
1922 sed -i -e 's/^\(PACKAGE_FOLDER\)=""/\1="$( echo "${BASH_SOURCE[0]}" | sed \"s!test.sh\\$!!\" )"/' \
1923 -e "s/^\(HT\)=0/\1=${HT}/" \
1924 -e "s/^\(MODE\)=0/\1=${MODE}/" \
1925 -e "s/^\(ATTACK\)=0/\1=${ATTACK}/" \
1926 ${OUTD}/test.sh
1927
1928 ${PACKAGE_CMD} ${OUTD}/${OUTD}.7z ${OUTD}/ &> /dev/null
1929
1930 fi