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