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