Add --mangle switch for mangling password before hashing
[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 ## magnum <john.magnum@hushmail.com>
7 ##
8 ## License.....: MIT
9 ##
10
11 # missing hash types: 5200,6211,6221,6231,6241,6251,6261,6271,6281
12
13 HASH_TYPES="0 10 11 12 20 21 22 23 30 40 50 60 100 101 110 111 112 120 121 122 125 130 131 132 133 140 141 150 160 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 13100 13200 13300 13400 13500 13600 13800"
14
15 #ATTACK_MODES="0 1 3 6 7"
16 ATTACK_MODES="0 1 3 7"
17
18 VECTOR_WIDTHS="1 2 4 8 16"
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 13200 13400 13600"
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 'all' => test sequentially vector-width ${VECTOR_WIDTHS}
1539
1540 -T OpenCL device-types to use :
1541 'gpu' => gpu devices (default)
1542 'cpu' => cpu devices
1543 'all' => gpu and cpu devices
1544
1545 -t Select test mode :
1546 'single' => single hash (default)
1547 'multi' => multi hash
1548 'all' => single and multi hash
1549
1550 -m Select hash type :
1551 'all' => all hash type supported
1552 (int) => hash type integer code (default : 0)
1553
1554 -a Select attack mode :
1555 'all' => all attack modes
1556 (int) => attack mode integer code (default : 0)
1557
1558 -x Select cpu architecture :
1559 '32' => 32 bit architecture
1560 '64' => 64 bit architecture (default)
1561
1562 -o Select operating system :
1563 'win' => windows operating system (use .exe file extension etc)
1564 'linux' => *nix based operating systems (.bin for binaries)
1565 'osx' => mac osx operating systems (.app for binaries)
1566
1567 -c Disables markov-chains
1568
1569 -p Package the tests into a .7z file
1570
1571 -d Use this folder as input/output folder for packaged tests
1572 (string) => path to folder
1573
1574 -h Show this help
1575
1576 EOF
1577
1578 exit 1
1579 }
1580
1581 BIN="hashcat"
1582 MARKOV="enabled"
1583 ATTACK=0
1584 MODE=0
1585 TYPE="null"
1586 VECTOR="default"
1587 HT=0
1588 PACKAGE=0
1589
1590 while getopts "V:T:t:m:a:b:hcpd:x:o:" opt; do
1591
1592 case ${opt} in
1593 "V")
1594 if [ ${OPTARG} == "1" ]; then
1595 VECTOR=1
1596 elif [ ${OPTARG} == "2" ]; then
1597 VECTOR=2
1598 elif [ ${OPTARG} == "4" ]; then
1599 VECTOR=4
1600 elif [ ${OPTARG} == "8" ]; then
1601 VECTOR=8
1602 elif [ ${OPTARG} == "16" ]; then
1603 VECTOR=16
1604 elif [ ${OPTARG} == "all" ]; then
1605 VECTOR="all"
1606 else
1607 usage
1608 fi
1609 ;;
1610
1611 "T")
1612 if [ ${OPTARG} == "gpu" ]; then
1613 OPTS="${OPTS} --opencl-device-types 2"
1614 TYPE="Gpu"
1615 elif [ ${OPTARG} == "cpu" ]; then
1616 OPTS="${OPTS} --opencl-device-types 1"
1617 TYPE="Cpu"
1618 elif [ ${OPTARG} == "all" ]; then
1619 OPTS="${OPTS} --opencl-device-types 1,2"
1620 TYPE="Cpu + Gpu"
1621 else
1622 usage
1623 fi
1624 ;;
1625
1626 "t")
1627 if [ ${OPTARG} == "single" ]; then
1628 MODE=0
1629 elif [ ${OPTARG} == "multi" ]; then
1630 MODE=1
1631 elif [ ${OPTARG} == "all" ]; then
1632 MODE=2
1633 else
1634 usage
1635 fi
1636 ;;
1637
1638 "m")
1639 if [ ${OPTARG} == "all" ]; then
1640 HT=65535
1641 else
1642 HT=${OPTARG}
1643 fi
1644 ;;
1645
1646 "a")
1647 if [ ${OPTARG} == "all" ]; then
1648 ATTACK=65535
1649 elif [ ${OPTARG} == "0" ]; then
1650 ATTACK=0
1651 elif [ ${OPTARG} == "1" ]; then
1652 ATTACK=1
1653 elif [ ${OPTARG} == "3" ]; then
1654 ATTACK=3
1655 elif [ ${OPTARG} == "6" ]; then
1656 ATTACK=6
1657 elif [ ${OPTARG} == "7" ]; then
1658 ATTACK=7
1659 else
1660 usage
1661 fi
1662 ;;
1663
1664 "c")
1665 OPTS="${OPTS} --markov-disable"
1666 MARKOV="disabled"
1667 ;;
1668
1669 "d")
1670 PACKAGE_FOLDER=$( echo ${OPTARG} | sed 's!/$!!g' )
1671 ;;
1672
1673 "p")
1674 PACKAGE=1
1675 ;;
1676
1677 "x")
1678 if [ ${OPTARG} == "32" ]; then
1679 ARCHITECTURE=32
1680 elif [ ${OPTARG} == "64" ]; then
1681 ARCHITECTURE=64
1682 else
1683 usage
1684 fi
1685 ;;
1686
1687 "o")
1688 if [ ${OPTARG} == "win" ]; then
1689 EXTENSION="exe"
1690 elif [ ${OPTARG} == "linux" ]; then
1691 EXTENSION="bin"
1692 elif [ ${OPTARG} == "osx" ]; then
1693 EXTENSION="app"
1694 else
1695 usage
1696 fi
1697 ;;
1698
1699 \?)
1700 usage
1701 ;;
1702
1703 "h")
1704 usage
1705 ;;
1706 esac
1707
1708 done
1709
1710 if [ "${TYPE}" == "null" ]; then
1711 TYPE="Gpu"
1712 OPTS="${OPTS} --opencl-device-types 2"
1713 fi
1714
1715 if [ -n "${ARCHITECTURE}" ]; then
1716
1717 BIN="${BIN}${ARCHITECTURE}"
1718
1719 fi
1720
1721 if [ -n "${EXTENSION}" ]; then
1722
1723 BIN="${BIN}.${EXTENSION}"
1724
1725 fi
1726
1727 if [ -n "${PACKAGE_FOLDER}" ]; then
1728
1729 if [ ! -e "${PACKAGE_FOLDER}" ]; then
1730 echo "! folder '${PACKAGE_FOLDER}' does not exist"
1731 exit 1
1732 fi
1733
1734 fi
1735
1736 if [ "${PACKAGE}" -eq 0 -o -z "${PACKAGE_FOLDER}" ]; then
1737
1738 # check existence of binary
1739 if [ ! -e "${BIN}" ]; then
1740 echo "! ${BIN} not found, please build binary before run test."
1741 exit 1
1742 fi
1743
1744 # filter by hash_type
1745 if [ ${HT} -ne 65535 ]; then
1746
1747 # validate filter
1748 check=0
1749 for hash_type in $(echo ${HASH_TYPES}); do
1750
1751 if [ ${HT} -ne ${hash_type} ]; then continue; fi
1752
1753 check=1
1754
1755 break
1756
1757 done
1758
1759 if [ ${check} -ne 1 ]; then
1760 echo "! invalid hash type selected ..."
1761 usage
1762 fi
1763
1764 fi
1765
1766 if [ -z "${PACKAGE_FOLDER}" ]; then
1767
1768 # make new dir
1769 mkdir -p ${OUTD}
1770
1771 # generate random test entry
1772 if [ ${HT} -eq 65535 ]; then
1773 perl tools/test.pl single > ${OUTD}/all.sh
1774 else
1775 perl tools/test.pl single ${HT} > ${OUTD}/all.sh
1776 fi
1777
1778 else
1779
1780 OUTD=${PACKAGE_FOLDER}
1781
1782 fi
1783
1784 rm -rf ${OUTD}/logfull.txt && touch ${OUTD}/logfull.txt
1785
1786 # populate array of hash types where we only should check if pass is in output (not both hash:pass)
1787 IFS=';' read -ra PASS_ONLY <<< "${MATCH_PASS_ONLY}"
1788 IFS=';' read -ra TIMEOUT_ALGOS <<< "${SLOW_ALGOS}"
1789
1790 IFS=';' read -ra NEVER_CRACK_ALGOS <<< "${NEVER_CRACK}"
1791
1792 # for these particular algos we need to save the output to a temporary file
1793 IFS=';' read -ra FILE_BASED_ALGOS <<< "${HASHFILE_ONLY}"
1794
1795 for hash_type in $(echo $HASH_TYPES); do
1796
1797 if [[ ${HT} -ne 65535 ]] && [[ ${HT} -ne ${hash_type} ]]; then continue; fi
1798
1799 if [ -z "${PACKAGE_FOLDER}" ]; then
1800
1801 # init test data
1802 init
1803
1804 else
1805
1806 echo "[ ${OUTD} ] > Run packaged test for hash type $hash_type."
1807
1808 fi
1809
1810 if [ "${PACKAGE}" -eq 0 ]; then
1811
1812 # should we check only the pass?
1813 contains ${hash_type} ${PASS_ONLY}
1814 pass_only=$?
1815
1816 contains ${hash_type} ${SLOW_ALGOS}
1817 IS_SLOW=$?
1818
1819 if [[ ${hash_type} -eq 400 ]]; then
1820 # we use phpass as slow hash for testing the AMP kernel
1821 IS_SLOW=0
1822 fi
1823
1824 OPTS_OLD=${OPTS}
1825 VECTOR_OLD=${VECTOR}
1826 for CUR_WIDTH in $(echo $VECTOR_WIDTHS); do
1827
1828 if [ "${VECTOR_OLD}" == "all" ] || [ "${VECTOR_OLD}" == "default" ] || [ "${VECTOR_OLD}" == "${CUR_WIDTH}" ]; then
1829
1830 if [ "${VECTOR_OLD}" == "default" ] && \
1831 [ "${CUR_WIDTH}" != "1" ] && \
1832 [ "${CUR_WIDTH}" != "4" ]; then
1833
1834 continue
1835 fi
1836
1837 VECTOR=${CUR_WIDTH}
1838 OPTS="${OPTS_OLD} --opencl-vector-width ${VECTOR}"
1839
1840 if [[ ${IS_SLOW} -eq 1 ]]; then
1841
1842 # run attack mode 0 (stdin)
1843 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 0 ]]; then attack_0; fi
1844
1845 else
1846
1847 # run attack mode 0 (stdin)
1848 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 0 ]]; then attack_0; fi
1849
1850 # run attack mode 1 (combinator)
1851 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 1 ]]; then attack_1; fi
1852
1853 # run attack mode 3 (bruteforce)
1854 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 3 ]]; then attack_3; fi
1855
1856 # run attack mode 6 (dict+mask)
1857 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 6 ]]; then attack_6; fi
1858
1859 # run attack mode 7 (mask+dict)
1860 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 7 ]]; then attack_7; fi
1861
1862 fi
1863 fi
1864 done
1865 OPTS="${OPTS_OLD}"
1866 VECTOR="${VECTOR_OLD}"
1867 fi
1868 done
1869
1870 else
1871
1872 OUTD=${PACKAGE_FOLDER}
1873
1874 fi
1875
1876 # fix logfile
1877 if [ "${PACKAGE}" -eq 0 ]; then
1878
1879 cat -A ${OUTD}/logfull.txt | sed -e 's/\^M \^M//g' | sed -e 's/\$$//g' > ${OUTD}/test_report.log
1880
1881 fi
1882
1883 rm -rf ${OUTD}/logfull.txt
1884
1885 if [ "${PACKAGE}" -eq 1 ]; then
1886
1887 echo "[ ${OUTD} ] > Generate package ${OUTD}/${OUTD}.7z"
1888
1889 cp "${BASH_SOURCE[0]}" ${OUTD}/test.sh
1890
1891 # if we package from a given folder, we need to check if e.g. the files needed for multi mode are there
1892
1893 if [ -n "${PACKAGE_FOLDER}" ]; then
1894
1895 MODE=2
1896
1897 ls "${PACKAGE_FOLDER}"/*multi* &> /dev/null
1898
1899 if [ "${?}" -ne 0 ]
1900 then
1901
1902 MODE=0
1903
1904 fi
1905
1906 HT=$(grep -o -- "-m *[0-9]*" ${PACKAGE_FOLDER}/all.sh | sort -u | sed 's/-m //' 2> /dev/null)
1907
1908 if [ -n "${HT}" ]; then
1909
1910 HT_COUNT=$(echo "${HT}" | wc -l)
1911
1912 if [ "${HT_COUNT}" -gt 1 ]; then
1913
1914 HT=65535
1915
1916 fi
1917
1918 fi
1919
1920 #ATTACK=65535 # more appropriate ?
1921 fi
1922
1923 # for convenience: 'run package' is default action for packaged test.sh ( + add other defaults too )
1924
1925 sed -i -e 's/^\(PACKAGE_FOLDER\)=""/\1="$( echo "${BASH_SOURCE[0]}" | sed \"s!test.sh\\$!!\" )"/' \
1926 -e "s/^\(HT\)=0/\1=${HT}/" \
1927 -e "s/^\(MODE\)=0/\1=${MODE}/" \
1928 -e "s/^\(ATTACK\)=0/\1=${ATTACK}/" \
1929 ${OUTD}/test.sh
1930
1931 ${PACKAGE_CMD} ${OUTD}/${OUTD}.7z ${OUTD}/ &> /dev/null
1932
1933 fi