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