Initial commit
[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 -b Select binary :
1541 'amd' => oclHashcat64.bin (default)
1542 'nvidia' => cudaHashcat64.bin
1543
1544 -x Select cpu architecture :
1545 '32' => 32 bit architecture
1546 '64' => 64 bit architecture (default)
1547
1548 -o Select operating system :
1549 'win' => windows operating system (use .exe file extension etc)
1550 'linux' => *nix based operating systems (.bin for binaries)
1551
1552 -c Disables markov-chains
1553
1554 -p Package the tests into a .7z file
1555
1556 -d Use this folder as input/output folder for packaged tests
1557 (string) => path to folder
1558
1559 -h Show this help
1560
1561 EOF
1562
1563 exit 1
1564 }
1565
1566 BN="amd"
1567 BIN="oclHashcat64.bin"
1568 MARKOV="enabled"
1569 ATTACK=0
1570 MODE=0
1571 HT=0
1572 PACKAGE=0
1573
1574 while getopts "t:m:a:b:hcpd:x:o:" opt; do
1575
1576 case ${opt} in
1577 "t")
1578 if [ ${OPTARG} == "single" ]; then
1579 MODE=0
1580 elif [ ${OPTARG} == "multi" ]; then
1581 MODE=1
1582 elif [ ${OPTARG} == "all" ]; then
1583 MODE=2
1584 else
1585 usage
1586 fi
1587 ;;
1588
1589 "m")
1590 if [ ${OPTARG} == "all" ]; then
1591 HT=65535
1592 else
1593 HT=${OPTARG}
1594 fi
1595 ;;
1596
1597 "a")
1598 if [ ${OPTARG} == "all" ]; then
1599 ATTACK=65535
1600 elif [ ${OPTARG} == "0" ]; then
1601 ATTACK=0
1602 elif [ ${OPTARG} == "1" ]; then
1603 ATTACK=1
1604 elif [ ${OPTARG} == "3" ]; then
1605 ATTACK=3
1606 elif [ ${OPTARG} == "6" ]; then
1607 ATTACK=6
1608 elif [ ${OPTARG} == "7" ]; then
1609 ATTACK=7
1610 else
1611 usage
1612 fi
1613 ;;
1614
1615 "b")
1616 if [ ${OPTARG} == "amd" ]; then
1617 BIN="oclHashcat64.bin"
1618 BN="amd"
1619 elif [ ${OPTARG} == "nvidia" ]; then
1620 BIN="cudaHashcat64.bin"
1621 BN="nvidia"
1622 else
1623 usage
1624 fi
1625 ;;
1626
1627 "c")
1628 OPTS="${OPTS} --markov-disable"
1629 MARKOV="disabled"
1630 ;;
1631
1632 "d")
1633 PACKAGE_FOLDER=$( echo ${OPTARG} | sed 's!/$!!g' )
1634 ;;
1635
1636 "p")
1637 PACKAGE=1
1638 ;;
1639
1640 "x")
1641 if [ ${OPTARG} == "32" ]; then
1642 ARCHITECTURE=32
1643 elif [ ${OPTARG} == "64" ]; then
1644 ARCHITECTURE=64
1645 else
1646 usage
1647 fi
1648 ;;
1649
1650 "o")
1651 if [ ${OPTARG} == "win" ]; then
1652 EXTENSION="exe"
1653 elif [ ${OPTARG} == "linux" ]; then
1654 EXTENSION="bin"
1655 else
1656 usage
1657 fi
1658 ;;
1659
1660 \?)
1661 usage
1662 ;;
1663
1664 "h")
1665 usage
1666 ;;
1667 esac
1668
1669 done
1670
1671 if [ -n "${ARCHITECTURE}" ]; then
1672
1673 BIN=$( echo ${BIN} | sed "s!64!${ARCHITECTURE}!" )
1674
1675 fi
1676
1677 if [ -n "${EXTENSION}" ]; then
1678
1679 BIN=$( echo ${BIN} | sed "s!\.bin!\.${EXTENSION}!" )
1680
1681 fi
1682
1683 if [ -n "${PACKAGE_FOLDER}" ]; then
1684
1685 if [ ! -e "${PACKAGE_FOLDER}" ]; then
1686 echo "! folder '${PACKAGE_FOLDER}' does not exist"
1687 exit 1
1688 fi
1689
1690 fi
1691
1692 if [ "${PACKAGE}" -eq 0 -o -z "${PACKAGE_FOLDER}" ]; then
1693
1694 # check existence of binary
1695 if [ ! -e "${BIN}" ]; then
1696 echo "! ${BIN} not found, please build binary before run test."
1697 exit 1
1698 fi
1699
1700 # filter by hash_type
1701 if [ ${HT} -ne 65535 ]; then
1702
1703 # validate filter
1704 check=0
1705 for hash_type in $(echo ${HASH_TYPES}); do
1706
1707 if [ ${HT} -ne ${hash_type} ]; then continue; fi
1708
1709 check=1
1710
1711 break
1712
1713 done
1714
1715 if [ ${check} -ne 1 ]; then
1716 echo "! invalid hash type selected ..."
1717 usage
1718 fi
1719
1720 fi
1721
1722 if [ -z "${PACKAGE_FOLDER}" ]; then
1723
1724 # make new dir
1725 mkdir -p ${OUTD}
1726
1727 # generate random test entry
1728 if [ ${HT} -eq 65535 ]; then
1729 perl tools/test.pl single > ${OUTD}/all.sh
1730 else
1731 perl tools/test.pl single ${HT} > ${OUTD}/all.sh
1732 fi
1733
1734 else
1735
1736 OUTD=${PACKAGE_FOLDER}
1737
1738 fi
1739
1740 rm -rf ${OUTD}/logfull.txt && touch ${OUTD}/logfull.txt
1741
1742 # populate array of hash types where we only should check if pass is in output (not both hash:pass)
1743 IFS=';' read -ra PASS_ONLY <<< "${MATCH_PASS_ONLY}"
1744 IFS=';' read -ra TIMEOUT_ALGOS <<< "${SLOW_ALGOS}"
1745
1746 IFS=';' read -ra NEVER_CRACK_ALGOS <<< "${NEVER_CRACK}"
1747
1748 # for these particular algos we need to save the output to a temporary file
1749 IFS=';' read -ra FILE_BASED_ALGOS <<< "${HASHFILE_ONLY}"
1750
1751 for hash_type in $(echo $HASH_TYPES); do
1752
1753 if [[ ${HT} -ne 65535 ]] && [[ ${HT} -ne ${hash_type} ]]; then continue; fi
1754
1755 if [ -z "${PACKAGE_FOLDER}" ]; then
1756
1757 # init test data
1758 init
1759
1760 else
1761
1762 echo "[ ${OUTD} ] > Run packaged test for hash type $hash_type."
1763
1764 fi
1765
1766 if [ "${PACKAGE}" -eq 0 ]; then
1767
1768 # should we check only the pass?
1769 contains ${hash_type} ${PASS_ONLY}
1770 pass_only=$?
1771
1772 contains ${hash_type} ${SLOW_ALGOS}
1773 IS_SLOW=$?
1774
1775 if [[ ${hash_type} -eq 400 ]]; then
1776
1777 # we use phpass as slow hash for testing the AMP kernel
1778 IS_SLOW=0
1779 fi
1780
1781 if [[ ${IS_SLOW} -eq 1 ]]; then
1782
1783 # run attack mode 0 (stdin)
1784 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 0 ]]; then attack_0; fi
1785
1786 else
1787 # run attack mode 0 (stdin)
1788 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 0 ]]; then attack_0; fi
1789
1790 # run attack mode 1 (combinator)
1791 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 1 ]]; then attack_1; fi
1792
1793 # run attack mode 3 (bruteforce)
1794 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 3 ]]; then attack_3; fi
1795
1796 # run attack mode 6 (dict+mask)
1797 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 6 ]]; then attack_6; fi
1798
1799 # run attack mode 7 (mask+dict)
1800 if [[ ${ATTACK} -eq 65535 ]] || [[ ${ATTACK} -eq 7 ]]; then attack_7; fi
1801 fi
1802 fi
1803
1804 done
1805
1806 else
1807
1808 OUTD=${PACKAGE_FOLDER}
1809
1810 fi
1811
1812 # fix logfile
1813 if [ "${PACKAGE}" -eq 0 ]; then
1814
1815 cat -A ${OUTD}/logfull.txt | sed -e 's/\^M \^M//g' | sed -e 's/\$$//g' > ${OUTD}/test_report_${BN}.log
1816
1817 fi
1818
1819 rm -rf ${OUTD}/logfull.txt
1820
1821 if [ "${PACKAGE}" -eq 1 ]; then
1822
1823 echo "[ ${OUTD} ] > Generate package ${OUTD}/${OUTD}.7z"
1824
1825 cp "${BASH_SOURCE[0]}" ${OUTD}/test.sh
1826
1827 # if we package from a given folder, we need to check if e.g. the files needed for multi mode are there
1828
1829 if [ -n "${PACKAGE_FOLDER}" ]; then
1830
1831 MODE=2
1832
1833 ls "${PACKAGE_FOLDER}"/*multi* &> /dev/null
1834
1835 if [ "${?}" -ne 0 ]
1836 then
1837
1838 MODE=0
1839
1840 fi
1841
1842 HT=$(grep -o -- "-m *[0-9]*" ${PACKAGE_FOLDER}/all.sh | sort -u | sed 's/-m //' 2> /dev/null)
1843
1844 if [ -n "${HT}" ]; then
1845
1846 HT_COUNT=$(echo "${HT}" | wc -l)
1847
1848 if [ "${HT_COUNT}" -gt 1 ]; then
1849
1850 HT=65535
1851
1852 fi
1853
1854 fi
1855
1856 #ATTACK=65535 # more appropriate ?
1857 fi
1858
1859 # for convenience: 'run package' is default action for packaged test.sh ( + add other defaults too )
1860
1861 sed -i -e 's/^\(PACKAGE_FOLDER\)=""/\1="$( echo "${BASH_SOURCE[0]}" | sed \"s!test.sh\\$!!\" )"/' \
1862 -e "s/^\(HT\)=0/\1=${HT}/" \
1863 -e "s/^\(MODE\)=0/\1=${MODE}/" \
1864 -e "s/^\(ATTACK\)=0/\1=${ATTACK}/" \
1865 ${OUTD}/test.sh
1866
1867 ${PACKAGE_CMD} ${OUTD}/${OUTD}.7z ${OUTD}/ &> /dev/null
1868
1869 fi