4 ## Authors.....: Gabriele Gristina <matrix@hashcat.net> / Jens Steube <jens.steube@gmail.com>
8 # missing hash types: 5200,6211,6221,6231,6241,6251,6261,6271,6281
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"
12 ATTACK_MODES
="0 1 3 6 7"
14 MATCH_PASS_ONLY
="2500 5300 5400 6600 6800 8200"
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"
22 OPTS
="--quiet --force --potfile-disable --runtime 200 --gpu-temp-disable -d 1 --weak-hash-threshold=0"
24 OUTD
="test_$(date +%s)"
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"
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"
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"
130 for element
in "${@:2}"; do
132 if [ "${element}" == "${1}" ]; then
143 if [ "${PACKAGE}" -eq 1 ]; then
145 echo "[ ${OUTD} ] > Generate tests for hash type $hash_type."
149 echo "[ ${OUTD} ] > Init test for hash type $hash_type."
153 rm -rf ${OUTD}/${hash_type}.sh ${OUTD}/${hash_type}_passwords.txt ${OUTD}/${hash_type}_hashes.txt
155 # create list of password and hashes of same type
156 grep " ${hash_type} '" ${OUTD}/all.sh > ${OUTD}/${hash_type}.sh
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
162 if [ "${hash_type}" -eq 10300 ]; then
163 cat ${OUTD}/${hash_type}.sh | cut -d' ' -f11- | cut -d"'" -f2 > ${OUTD}/${hash_type}_hashes.txt
167 rm -rf ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2
168 touch ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2
170 # foreach password entry split password in 2 (skip first entry, is len 1)
173 # minimum password length
177 if [ "${hash_type}" -eq 2500 ]; then
179 min_len=7 # means length 8, since we start with 0
183 while read -u 9 pass; do
185 if [ ${i} -gt 1 ]; then
187 # split password, 'i' is the len
191 # special case (passwords longer than expected)
194 if [ "${pass_len}" -gt 1 ]
197 p1=$((p1 + ${min_len}))
198 p0=$((p0 + ${min_len}))
200 if [ "${p1}" -gt ${pass_len} ]; then
207 # add splitted password to dicts
209 echo ${pass} | cut -c -${p0} >> ${OUTD}/${hash_type}_dict1
210 echo ${pass} | cut -c ${p1}- >> ${OUTD}/${hash_type}_dict2
217 done 9< ${OUTD}/${hash_type}_passwords.txt
221 if [ "${hash_type}" -eq 2500 ]; then
223 min_len=7 # means length 8, since we start with 0
227 # generate multiple pass/hash foreach len (2 to 8)
228 if [ ${MODE} -ge 1 ]; then
230 for ((i = 2; i < 9; i++)); do
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}
236 perl tools/test.pl single ${hash_type} ${i} > ${OUTD}/${hash_type}_multi_${i}.txt
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
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
245 # split password, 'i' is the len
249 p0=$((p0 + ${min_len}))
250 p1=$((p1 + ${min_len}))
252 while read -u 9 pass; do
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}
258 done 9< ${OUTD}/${hash_type}_passwords_multi_${i}.txt
271 if [ ${RET} -ne 0 ]; then
274 if contains ${hash_type} ${NEVER_CRACK_ALGOS}; then
276 echo "password not found
, cmdline
: ${CMD}" &>> ${OUTD}/logfull.txt
283 echo "timeout reached
, cmdline
: ${CMD}" &>> ${OUTD}/logfull.txt
288 if [ "${pass_only}" -eq 1 ]; then
289 echo "plains not found
in output
, cmdline
: ${CMD}" &>> ${OUTD}/logfull.txt
291 echo "hash:plains not matched
in output
, cmdline
: ${CMD}" &>> ${OUTD}/logfull.txt
297 echo "! unhandled
return code
${RET}, cmdline : ${CMD}" $>> ${OUTD}/logfull.txt
298 echo "! unhandled return code, see ${OUTD}/logfull.txt for details."
309 if ! contains
${hash_type} ${FILE_BASED_ALGOS}; then
316 if [ ${MODE} -ne 1 ]; then
323 echo "> Testing hash type $hash_type with attack mode 0, markov ${MARKOV}, single hash." &>> ${OUTD}/logfull.txt
327 if ! contains
${hash_type} ${TIMEOUT_ALGOS}; then
335 while read -u 9 line
; do
337 if [ "${i}" -ge ${max} ]; then
343 hash="$(echo "$line" | cut -d\' -f2)"
344 pass
="$(echo "$line" | cut -d' ' -f3)"
346 if [ -z "${hash}" ]; then
352 if [ "${file_only}" -eq 1 ]; then
354 temp_file
="${OUTD}/${hash_type}_filebased_only_temp.txt"
355 echo ${hash} | base64
-d > ${temp_file}
360 CMD
="echo -n "${pass}" | ./${BIN} ${OPTS} -a 0 -m ${hash_type} '${hash}'"
362 echo -n "[ len $((i + 1)) ] " &>> ${OUTD}/logfull.txt
364 output=$(echo -n "${pass}" | ./${BIN} ${OPTS} -a 0 -m ${hash_type} "${hash}" 2>&1)
368 echo "${output}" >> ${OUTD}/logfull.txt
370 if [ "${ret}" -eq 0 ]; then
372 if [ ${pass_only} -eq 1 ]; then
375 search="${hash}:${pass}"
378 echo "${output}" | grep -F "${search}" &> /dev/null
380 if [ "${?}" -ne 0 ]; then
392 done 9< ${OUTD}/${hash_type}.sh
396 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
400 elif [ "${e_to}" -ne 0 ]; then
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"
411 if [ ${MODE} -ne 0 ]; then
418 echo "> Testing hash type $hash_type with attack mode 0, markov ${MARKOV}, multi hash." &>> ${OUTD}/logfull.txt
420 hash_file=${OUTD}/${hash_type}_hashes.txt
422 # if file_only -> decode all base64 "hashes" and put them in the temporary file
424 if [ "${file_only}" -eq 1 ]; then
426 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
429 hash_file=${temp_file}
431 while read base64_hash; do
433 echo -n ${base64_hash} | base64 -d >> ${temp_file}
435 done < ${OUTD}/${hash_type}_hashes.txt
439 CMD="cat ${OUTD}/${hash_type}_passwords.txt | ./${BIN} ${OPTS} -a 0 -m ${hash_type} ${hash_file}"
441 output=$(cat ${OUTD}/${hash_type}_passwords.txt | ./${BIN} ${OPTS} -a 0 -m ${hash_type} ${hash_file} 2>&1)
445 echo "${output}" >> ${OUTD}/logfull.txt
447 if [ "${ret}" -eq 0 ]; then
451 while read -u 9 hash; do
453 pass=$(sed -n ${i}p ${OUTD}/${hash_type}_passwords.txt)
455 if [ ${pass_only} -eq 1 ]; then
458 search="${hash}:${pass}"
461 echo "${output}" | grep -F "${search}" &> /dev/null
463 if [ "${?}" -ne 0 ]; then
473 done 9< ${OUTD}/${hash_type}_hashes.txt
481 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
485 elif [ "${e_to}" -ne 0 ]; then
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"
500 if ! contains ${hash_type} ${FILE_BASED_ALGOS}; then
507 if [ ${MODE} -ne 1 ]; then
514 echo "> Testing hash type $hash_type with attack mode 1, markov ${MARKOV}, single hash." &>> ${OUTD}/logfull.txt
516 while read -u 9 hash; do
518 if [ $i -gt 1 ]; then
520 if [ "${file_only}" -eq 1 ]; then
522 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
523 echo ${hash} | base64 -d > ${temp_file}
528 CMD="./${BIN} ${OPTS} -a 1 -m ${hash_type} '${hash}' ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2"
530 echo -n "[ len $i ] " &>> ${OUTD}/logfull.txt
532 output=$(./${BIN} ${OPTS} -a 1 -m ${hash_type} "${hash}" ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2 2>&1)
536 echo "${output}" >> ${OUTD}/logfull.txt
538 if [ "${ret}" -eq 0 ]; then
542 line_dict1=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict1)
543 line_dict2=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict2)
545 if [ ${pass_only} -eq 1 ]; then
546 search=":${line_dict1}${line_dict2}"
548 search="${hash}:${line_dict1}${line_dict2}"
551 echo "${output}" | grep -F "${search}" &> /dev/null
553 if [ "${?}" -ne 0 ]; then
567 done 9< ${OUTD}/${hash_type}_hashes.txt
571 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
575 elif [ "${e_to}" -ne 0 ]; then
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"
586 if [ ${MODE} -ne 0 ]; then
595 if [ ${hash_type} -eq 2500 ]; then
597 elif [ ${hash_type} -eq 5800 ]; then
599 elif [ ${hash_type} -eq 3000 ]; then
601 elif [ ${hash_type} -eq 2100 ]; then
603 elif [ ${hash_type} -eq 1500 ]; then
605 elif [ ${hash_type} -eq 7700 ]; then
607 elif [ ${hash_type} -eq 8500 ]; then
611 hash_file=${OUTD}/${hash_type}_multihash_combi.txt
613 tail -n ${offset} ${OUTD}/${hash_type}_hashes.txt > ${hash_file}
615 # if file_only -> decode all base64 "hashes" and put them in the temporary file
617 if [ "${file_only}" -eq 1 ]; then
619 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
622 hash_file=${temp_file}
624 while read base64_hash; do
626 echo -n ${base64_hash} | base64 -d >> ${temp_file}
628 done < ${OUTD}/${hash_type}_multihash_combi.txt
632 CMD="./${BIN} ${OPTS} -a 1 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2"
634 echo "> Testing hash type $hash_type with attack mode 1, markov ${MARKOV}, multi hash." &>> ${OUTD}/logfull.txt
636 output=$(./${BIN} ${OPTS} -a 1 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2 2>&1)
640 echo "${output}" >> ${OUTD}/logfull.txt
642 if [ "${ret}" -eq 0 ]; then
646 while read -u 9 hash; do
648 line_nr=$((offset - i))
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)
653 if [ ${pass_only} -eq 1 ]; then
654 search=":${line_dict1}${line_dict2}"
656 search="${hash}:${line_dict1}${line_dict2}"
659 echo "${output}" | grep -F "${search}" &> /dev/null
661 if [ "${?}" -ne 0 ]; then
671 done 9< ${OUTD}/${hash_type}_multihash_combi.txt
679 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
683 elif [ "${e_to}" -ne 0 ]; then
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"
698 if ! contains ${hash_type} ${FILE_BASED_ALGOS}; then
705 if [ ${MODE} -ne 1 ]; then
712 echo "> Testing hash type $hash_type with attack mode 3, markov ${MARKOV}, single hash." &>> ${OUTD}/logfull.txt
717 # some algos have a minimum password length
719 if [ "${hash_type}" -eq 2500 ];then
728 while read -u 9 hash; do
730 if [ "${i}" -gt 6 ]; then
732 if ! contains ${hash_type} ${TIMEOUT_ALGOS}; then
740 if [ "${file_only}" -eq 1 ]; then
742 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
743 echo ${hash} | base64 -d > ${temp_file}
748 mask=${mask_3[$((i + ${mask_offset}))]}
750 # modify "default" mask if needed (and set custom charset to reduce keyspace)
752 if [ "${hash_type}" -eq 2500 ]; then
754 pass=$(sed -n ${i}p ${OUTD}/${hash_type}_passwords.txt)
758 # replace the first x positions in the mask with ?d's
760 # first: remove first i (== amount) chars
762 mask
=$
(echo ${mask} | cut
-b $
((i
+ 1))-)
766 for i
in $
(seq 1 ${i}); do
774 CMD
="./${BIN} ${OPTS} -a 3 -m ${hash_type} '${hash}' ${mask}"
776 echo -n "[ len $i ] " &>> ${OUTD}/logfull.txt
778 output
=$
(.
/${BIN} ${OPTS} -a 3 -m ${hash_type} "${hash}" ${mask} 2>&1)
782 echo "${output}" >> ${OUTD}/logfull.txt
784 if [ "${ret}" -eq 0 ]; then
786 line_dict
=$
(sed -n ${i}p ${OUTD}/${hash_type}_passwords.txt
)
788 if [ ${pass_only} -eq 1 ]; then
789 search
=":${line_dict}"
791 search
="${hash}:${line_dict}"
794 echo "${output}" |
grep -F "${search}" &> /dev
/null
796 if [ "${?}" -ne 0 ]; then
806 if [ $i -eq ${max} ]; then break; fi
810 done 9< ${OUTD}/${hash_type}_hashes.txt
814 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
818 elif [ "${e_to}" -ne 0 ]; then
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"
829 if [ ${MODE} -ne 0 ]; then
838 if ! contains
${hash_type} ${TIMEOUT_ALGOS}; then
846 if [ "${hash_type}" -eq 2500 ]; then
853 hash_file
=${OUTD}/${hash_type}_multihash_bruteforce.txt
855 head -n $
((increment_max
- ${increment_min} + 1)) ${OUTD}/${hash_type}_hashes.txt > ${hash_file}
857 # if file_only -> decode all base64 "hashes" and put them in the temporary file
859 if [ "${file_only}" -eq 1 ]; then
861 temp_file
="${OUTD}/${hash_type}_filebased_only_temp.txt"
864 hash_file
=${temp_file}
866 while read base64_hash
; do
868 echo -n ${base64_hash} | base64
-d >> ${temp_file}
870 done < ${OUTD}/${hash_type}_multihash_bruteforce.txt
877 # modify "default" mask if needed (and set custom charset to reduce keyspace)
879 if [ "${hash_type}" -eq 2500 ]; then
881 mask
="?d?d?d?d?d?1?2?3?4"
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)
895 # divide each charset position by 2 since each of them occupies 2 positions in the mask
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))
904 while read -u 9 hash; do
906 pass
=$
(sed -n ${i}p ${OUTD}/${hash_type}_passwords.txt
)
909 char
=$
(echo "${pass}" | cut
-b ${charset_1_pos})
910 charset_1
=$
(echo -e "${charset_1}\n${char}")
913 char
=$
(echo "${pass}" | cut
-b ${charset_2_pos})
914 charset_2
=$
(echo -e "${charset_2}\n${char}")
917 char
=$
(echo "${pass}" | cut
-b ${charset_3_pos})
918 charset_3
=$
(echo -e "${charset_3}\n${char}")
921 char
=$
(echo "${pass}" | cut
-b ${charset_4_pos})
922 charset_4
=$
(echo -e "${charset_4}\n${char}")
926 done 9< ${OUTD}/${hash_type}_multihash_bruteforce.txt
928 # just make sure that all custom charset fields are initialized
930 if [ -z "${charset_1}" ]; then
936 if [ -z "${charset_2}" ]; then
942 if [ -z "${charset_3}" ]; then
948 if [ -z "${charset_4}" ]; then
954 # unique and remove new lines
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')
961 custom_charsets
="-1 ${charset_1} -2 ${charset_2} -3 ${charset_3} -4 ${charset_4}"
964 CMD
="./${BIN} ${OPTS} -a 3 -m ${hash_type} --increment --increment-min ${increment_min} --increment-max ${increment_max} ${custom_charsets} ${hash_file} ${mask} "
966 echo "> Testing hash type $hash_type with attack mode 3, markov ${MARKOV}, multi hash." &>> ${OUTD}/logfull.txt
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)
972 echo "${output}" >> ${OUTD}/logfull.txt
974 if [ "${ret}" -eq 0 ]; then
978 while read -u 9 hash; do
980 pass
=$
(sed -n ${i}p ${OUTD}/${hash_type}_passwords.txt
)
982 if [ ${pass_only} -eq 1 ]; then
985 search
="${hash}:${pass}"
988 echo "${output}" |
grep -F "${search}" &> /dev
/null
990 if [ "${?}" -ne 0 ]; then
1000 done 9< ${OUTD}/${hash_type}_multihash_bruteforce.txt
1008 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
1012 elif [ "${e_to}" -ne 0 ]; then
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"
1027 if ! contains
${hash_type} ${FILE_BASED_ALGOS}; then
1034 if [ ${MODE} -ne 1 ]; then
1041 echo "> Testing hash type $hash_type with attack mode 6, markov ${MARKOV}, single hash." &>> ${OUTD}/logfull.txt
1047 if [ "${hash_type}" -eq 2500 ]; then
1053 while read -u 9 hash; do
1055 if [ "${i}" -gt 6 ]; then
1057 if ! contains
${hash_type} ${TIMEOUT_ALGOS}; then
1065 if [ $i -gt 1 ]; then
1067 if [ "${file_only}" -eq 1 ]; then
1069 temp_file
="${OUTD}/${hash_type}_filebased_only_temp.txt"
1070 echo ${hash} | base64
-d > ${temp_file}
1075 CMD
="./${BIN} ${OPTS} -a 6 -m ${hash_type} '${hash}' ${OUTD}/${hash_type}_dict1 ${mask_6[$i]}"
1077 echo -n "[ len $i ] " &>> ${OUTD}/logfull.txt
1079 output
=$
(.
/${BIN} ${OPTS} -a 6 -m ${hash_type} "${hash}" ${OUTD}/${hash_type}_dict1 ${mask_6[$i]} 2>&1)
1083 echo "${output}" >> ${OUTD}/logfull.txt
1085 if [ "${ret}" -eq 0 ]; then
1089 line_dict1
=$
(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict1
)
1090 line_dict2
=$
(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict2
)
1092 if [ ${pass_only} -eq 1 ]; then
1093 search
=":${line_dict1}${line_dict2}"
1095 search
="${hash}:${line_dict1}${line_dict2}"
1098 echo "${output}" |
grep -F "${search}" &> /dev
/null
1100 if [ "${?}" -ne 0 ]; then
1112 if [ "${i}" -eq ${max} ]; then break; fi
1116 done 9< ${OUTD}/${hash_type}_hashes.txt
1120 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
1124 elif [ "${e_to}" -ne 0 ]; then
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"
1135 if [ ${MODE} -ne 0 ]; then
1144 if [ ${hash_type} -eq 2500 ]; then
1146 elif [ ${hash_type} -eq 3000 ]; then
1148 elif [ ${hash_type} -eq 7700 ]; then
1150 elif [ ${hash_type} -eq 8500 ]; then
1154 if ! contains
${hash_type} ${TIMEOUT_ALGOS}; then
1158 if [ "${hash_type}" -eq 3200 ]; then
1166 for ((i
= 2; i
< ${max}; i
++)); do
1168 hash_file
=${OUTD}/${hash_type}_hashes_multi_${i}.txt
1170 # if file_only -> decode all base64 "hashes" and put them in the temporary file
1172 if [ "${file_only}" -eq 1 ]; then
1174 temp_file
="${OUTD}/${hash_type}_filebased_only_temp.txt"
1177 hash_file
=${temp_file}
1179 while read base64_hash
; do
1181 echo -n ${base64_hash} | base64
-d >> ${temp_file}
1183 done < ${OUTD}/${hash_type}_hashes_multi_${i}.txt
1187 CMD
="./${BIN} ${OPTS} -a 6 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1_multi_${i} ${mask_6[$i]}"
1189 echo "> Testing hash type $hash_type with attack mode 6, markov ${MARKOV}, multi hash with word len ${i}." &>> ${OUTD}/logfull.txt
1191 output=$(./${BIN} ${OPTS} -a 6 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1_multi_${i} ${mask_6[$i]} 2>&1)
1195 echo "${output}" >> ${OUTD}/logfull.txt
1197 if [ "${ret}" -eq 0 ]; then
1201 while read -u 9 hash; do
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})
1206 if [ ${pass_only} -eq 1 ]; then
1207 search=":${line_dict1}${line_dict2}"
1209 search="${hash}:${line_dict1}${line_dict2}"
1212 echo "${output}" | grep -F "${search}" &> /dev/null
1214 if [ "${?}" -ne 0 ]; then
1224 done 9< ${OUTD}/${hash_type}_hashes_multi_${i}.txt
1234 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
1238 elif [ "${e_to}" -ne 0 ]; then
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
"
1253 if ! contains ${hash_type} ${FILE_BASED_ALGOS}; then
1260 if [ ${MODE} -ne 1 ]; then
1267 echo "> Testing
hash type $hash_type with attack mode
7, markov
${MARKOV}, single
hash.
" &>> ${OUTD}/logfull.txt
1271 if [ "${hash_type}" -eq 2500 ]; then
1279 while read -u 9 hash; do
1281 if [ $i -gt 1 ]; then
1283 if [ "${file_only}" -eq 1 ]; then
1285 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt
"
1286 echo ${hash} | base64 -d > ${temp_file}
1293 # adjust mask if needed
1295 if [ "${hash_type}" -eq 2500 ]; then
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)
1302 pass_part_2_len=${#pass_part_2}
1304 pass=${pass_part_1}${pass_part_2}
1307 # add first x chars of password to mask and append the (old) mask
1310 mask_len=$((mask_len / 2))
1312 mask_prefix=$(echo ${pass} | cut -b -$((pass_len - ${mask_len} - ${pass_part_2_len})))
1313 mask=${mask_prefix}${mask}
1317 CMD=".
/${BIN} ${OPTS} -a 7 -m ${hash_type} '${hash}' ${mask} ${OUTD}/${hash_type}_dict2
"
1319 echo -n "[ len
$i ] " &>> ${OUTD}/logfull.txt
1321 output=$(./${BIN} ${OPTS} -a 7 -m ${hash_type} "${hash}" ${mask} ${OUTD}/${hash_type}_dict2 2>&1)
1325 echo "${output}" >> ${OUTD}/logfull.txt
1327 if [ "${ret}" -eq 0 ]; then
1331 line_dict1=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict1)
1332 line_dict2=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict2)
1334 if [ ${pass_only} -eq 1 ]; then
1335 search=":${line_dict1}${line_dict2}"
1337 search="${hash}:${line_dict1}${line_dict2}"
1340 echo "${output}" | grep -F "${search}" &> /dev/null
1342 if [ "${?}" -ne 0 ]; then
1354 if [ $i -eq ${max} ]; then break; fi
1358 done 9< ${OUTD}/${hash_type}_hashes.txt
1362 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
1366 elif [ "${e_to}" -ne 0 ]; then
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
"
1377 if [ ${MODE} -ne 0 ]; then
1386 if [ ${hash_type} -eq 2500 ]; then
1388 elif [ ${hash_type} -eq 3000 ]; then
1390 elif [ ${hash_type} -eq 7700 ]; then
1392 elif [ ${hash_type} -eq 8500 ]; then
1396 if ! contains ${hash_type} ${TIMEOUT_ALGOS}; then
1400 if [ "${hash_type}" -eq 3200 ]; then
1408 for ((i = 2; i < ${max}; i++)); do
1410 hash_file=${OUTD}/${hash_type}_hashes_multi_${i}.txt
1411 dict_file=${OUTD}/${hash_type}_dict2_multi_${i}
1415 # if file_only -> decode all base64 "hashes
" and put them in the temporary file
1417 if [ "${file_only}" -eq 1 ]; then
1419 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt
"
1422 hash_file=${temp_file}
1424 while read base64_hash; do
1426 echo -n ${base64_hash} | base64 -d >> ${temp_file}
1428 done < ${OUTD}/${hash_type}_hashes_multi_${i}.txt
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]
1433 dict_file=${OUTD}/${hash_type}_dict2_multi_${i}_longer
1437 mask_len=$((mask_len / 2))
1441 while read -u 9 hash; do
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})
1446 pass="${pass_part_1}${pass_part_2}"
1448 pass_suffix=$(echo "${pass}" | cut -b $((mask_len + 1))-)
1450 echo "${pass_suffix}" >> ${dict_file}
1454 done 9< ${OUTD}/${hash_type}_hashes_multi_${i}.txt
1458 CMD=".
/${BIN} ${OPTS} -a 7 -m ${hash_type} ${hash_file} ${mask} ${dict_file}"
1460 echo "> Testing
hash type $hash_type with attack mode
7, markov
${MARKOV}, multi hash with word len ${i}." &>> ${OUTD}/logfull.txt
1462 output
=$
(.
/${BIN} ${OPTS} -a 7 -m ${hash_type} ${hash_file} ${mask} ${dict_file} 2>&1)
1466 echo "${output}" >> ${OUTD}/logfull.txt
1468 if [ "${ret}" -eq 0 ]; then
1472 while read -u 9 hash; do
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})
1477 if [ ${pass_only} -eq 1 ]; then
1478 search
=":${line_dict1}${line_dict2}"
1480 search
="${hash}:${line_dict1}${line_dict2}"
1483 echo "${output}" |
grep -F "${search}" &> /dev
/null
1485 if [ "${?}" -ne 0 ]; then
1495 done 9< ${OUTD}/${hash_type}_hashes_multi_${i}.txt
1505 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
1509 elif [ "${e_to}" -ne 0 ]; then
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"
1523 > Usage : ${0} <options>
1527 -t Select test mode :
1528 'single' => single hash (default)
1529 'multi' => multi hash
1530 'all' => single and multi hash
1532 -m Select hash type :
1533 'all' => all hash type supported
1534 (int) => hash type integer code (default : 0)
1536 -a Select attack mode :
1537 'all' => all attack modes
1538 (int) => attack mode integer code (default : 0)
1541 'amd' => oclHashcat64.bin (default)
1542 'nvidia' => cudaHashcat64.bin
1544 -x Select cpu architecture :
1545 '32' => 32 bit architecture
1546 '64' => 64 bit architecture (default)
1548 -o Select operating system :
1549 'win' => windows operating system (use .exe file extension etc)
1550 'linux' => *nix based operating systems (.bin for binaries)
1552 -c Disables markov-chains
1554 -p Package the tests into a .7z file
1556 -d Use this folder as input/output folder for packaged tests
1557 (string) => path to folder
1567 BIN
="oclHashcat64.bin"
1574 while getopts "t:m:a:b:hcpd:x:o:" opt
; do
1578 if [ ${OPTARG} == "single" ]; then
1580 elif [ ${OPTARG} == "multi" ]; then
1582 elif [ ${OPTARG} == "all" ]; then
1590 if [ ${OPTARG} == "all" ]; then
1598 if [ ${OPTARG} == "all" ]; then
1600 elif [ ${OPTARG} == "0" ]; then
1602 elif [ ${OPTARG} == "1" ]; then
1604 elif [ ${OPTARG} == "3" ]; then
1606 elif [ ${OPTARG} == "6" ]; then
1608 elif [ ${OPTARG} == "7" ]; then
1616 if [ ${OPTARG} == "amd" ]; then
1617 BIN
="oclHashcat64.bin"
1619 elif [ ${OPTARG} == "nvidia" ]; then
1620 BIN
="cudaHashcat64.bin"
1628 OPTS
="${OPTS} --markov-disable"
1633 PACKAGE_FOLDER
=$
( echo ${OPTARG} |
sed 's!/$!!g' )
1641 if [ ${OPTARG} == "32" ]; then
1643 elif [ ${OPTARG} == "64" ]; then
1651 if [ ${OPTARG} == "win" ]; then
1653 elif [ ${OPTARG} == "linux" ]; then
1671 if [ -n "${ARCHITECTURE}" ]; then
1673 BIN
=$
( echo ${BIN} |
sed "s!64!${ARCHITECTURE}!" )
1677 if [ -n "${EXTENSION}" ]; then
1679 BIN
=$
( echo ${BIN} |
sed "s!\.bin!\.${EXTENSION}!" )
1683 if [ -n "${PACKAGE_FOLDER}" ]; then
1685 if [ ! -e "${PACKAGE_FOLDER}" ]; then
1686 echo "! folder '${PACKAGE_FOLDER}' does not exist"
1692 if [ "${PACKAGE}" -eq 0 -o -z "${PACKAGE_FOLDER}" ]; then
1694 # check existence of binary
1695 if [ ! -e "${BIN}" ]; then
1696 echo "! ${BIN} not found, please build binary before run test."
1700 # filter by hash_type
1701 if [ ${HT} -ne 65535 ]; then
1705 for hash_type
in $
(echo ${HASH_TYPES}); do
1707 if [ ${HT} -ne ${hash_type} ]; then continue; fi
1715 if [ ${check} -ne 1 ]; then
1716 echo "! invalid hash type selected ..."
1722 if [ -z "${PACKAGE_FOLDER}" ]; then
1727 # generate random test entry
1728 if [ ${HT} -eq 65535 ]; then
1729 perl tools
/test.pl single
> ${OUTD}/all.sh
1731 perl tools
/test.pl single
${HT} > ${OUTD}/all.sh
1736 OUTD
=${PACKAGE_FOLDER}
1740 rm -rf ${OUTD}/logfull.txt
&& touch ${OUTD}/logfull.txt
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}"
1746 IFS
=';' read -ra NEVER_CRACK_ALGOS
<<< "${NEVER_CRACK}"
1748 # for these particular algos we need to save the output to a temporary file
1749 IFS
=';' read -ra FILE_BASED_ALGOS
<<< "${HASHFILE_ONLY}"
1751 for hash_type
in $
(echo $HASH_TYPES); do
1753 if [[ ${HT} -ne 65535 ]] && [[ ${HT} -ne ${hash_type} ]]; then continue; fi
1755 if [ -z "${PACKAGE_FOLDER}" ]; then
1762 echo "[ ${OUTD} ] > Run packaged test for hash type $hash_type."
1766 if [ "${PACKAGE}" -eq 0 ]; then
1768 # should we check only the pass?
1769 contains
${hash_type} ${PASS_ONLY}
1772 contains
${hash_type} ${SLOW_ALGOS}
1775 if [[ ${hash_type} -eq 400 ]]; then
1776 # we use phpass as slow hash for testing the AMP kernel
1780 if [[ ${IS_SLOW} -eq 1 ]]; then
1782 # run attack mode 0 (stdin)
1783 if [[ ${ATTACK} -eq 65535 ]] ||
[[ ${ATTACK} -eq 0 ]]; then attack_0
; fi
1786 # run attack mode 0 (stdin)
1787 if [[ ${ATTACK} -eq 65535 ]] ||
[[ ${ATTACK} -eq 0 ]]; then attack_0
; fi
1789 # run attack mode 1 (combinator)
1790 if [[ ${ATTACK} -eq 65535 ]] ||
[[ ${ATTACK} -eq 1 ]]; then attack_1
; fi
1792 # run attack mode 3 (bruteforce)
1793 if [[ ${ATTACK} -eq 65535 ]] ||
[[ ${ATTACK} -eq 3 ]]; then attack_3
; fi
1795 # run attack mode 6 (dict+mask)
1796 if [[ ${ATTACK} -eq 65535 ]] ||
[[ ${ATTACK} -eq 6 ]]; then attack_6
; fi
1798 # run attack mode 7 (mask+dict)
1799 if [[ ${ATTACK} -eq 65535 ]] ||
[[ ${ATTACK} -eq 7 ]]; then attack_7
; fi
1807 OUTD
=${PACKAGE_FOLDER}
1812 if [ "${PACKAGE}" -eq 0 ]; then
1814 cat -A ${OUTD}/logfull.txt | sed -e 's/\^M \^M//g' | sed -e 's/\$$//g' > ${OUTD}/test_report_${BN}.log
1818 rm -rf ${OUTD}/logfull.txt
1820 if [ "${PACKAGE}" -eq 1 ]; then
1822 echo "[ ${OUTD} ] > Generate package ${OUTD}/${OUTD}.7z"
1824 cp "${BASH_SOURCE[0]}" ${OUTD}/test.sh
1826 # if we package from a given folder, we need to check if e.g. the files needed for multi mode are there
1828 if [ -n "${PACKAGE_FOLDER}" ]; then
1832 ls "${PACKAGE_FOLDER}"/*multi
* &> /dev
/null
1841 HT
=$
(grep -o -- "-m *[0-9]*" ${PACKAGE_FOLDER}/all.sh |
sort -u |
sed 's/-m //' 2> /dev
/null
)
1843 if [ -n "${HT}" ]; then
1845 HT_COUNT
=$
(echo "${HT}" |
wc -l)
1847 if [ "${HT_COUNT}" -gt 1 ]; then
1855 #ATTACK=65535 # more appropriate ?
1858 # for convenience: 'run package' is default action for packaged test.sh ( + add other defaults too )
1860 sed -i -e 's/^\(PACKAGE_FOLDER\)=""/\1="$( echo "${BASH_SOURCE[0]}" | sed \"s!test.sh\\$!!\" )"/' \
1861 -e "s/^\(HT\)=0/\1=${HT}/" \
1862 -e "s/^\(MODE\)=0/\1=${MODE}/" \
1863 -e "s/^\(ATTACK\)=0/\1=${ATTACK}/" \
1866 ${PACKAGE_CMD} ${OUTD}/${OUTD}.7z ${OUTD}/ &> /dev
/null