4 ## Authors.....: Gabriele Gristina <matrix@hashcat.net>
5 ## Jens Steube <jens.steube@gmail.com>
10 # missing hash types: 5200,6211,6221,6231,6241,6251,6261,6271,6281
12 HASH_TYPES
="0 10 11 12 20 21 22 23 30 40 50 60 100 101 110 111 112 120 121 122 130 131 132 140 141 150 160 190 200 300 400 500 900 1000 1100 1400 1410 1420 1430 1440 1441 1450 1460 1500 1600 1700 1710 1711 1720 1722 1730 1731 1740 1750 1760 1800 2100 2400 2410 2500 2600 2611 2612 2711 2811 3000 3100 3200 3710 3711 3800 4300 4400 4500 4700 4800 4900 5000 5100 5300 5400 5500 5600 5700 5800 6000 6100 6300 6400 6500 6600 6700 6800 6900 7100 7200 7300 7400 7500 7600 7700 7800 7900 8000 8100 8200 8300 8400 8500 8600 8700 8900 9100 9200 9300 9400 9500 9600 9700 9800 9900 10000 10100 10200 10300 10400 10500 10600 10700 10800 10900 11000 11100 11200 11300 11400 11500 11600 11900 12000 12100 12200 12300 12400 12600 12800 12900 13000"
14 ATTACK_MODES
="0 1 3 6 7"
16 MATCH_PASS_ONLY
="2500 5300 5400 6600 6800 8200"
22 SLOW_ALGOS
="400 500 501 1600 1800 2100 2500 3200 5200 5800 6211 6221 6231 6241 6251 6261 6271 6281 6300 6400 6500 6600 6700 6800 7100 7200 7400 7900 8200 8800 8900 9000 9100 9200 9300 9400 9500 9600 10000 10300 10500 10700 10900 11300 11600 11900 12000 12100 12200 12300 12400 12500 12800 12900 13000"
24 OPTS
="--quiet --force --potfile-disable --runtime 200 --gpu-temp-disable --weak-hash-threshold=0 --opencl-device-types 2 --opencl-vector-width 2"
26 OUTD
="test_$(date +%s)"
36 mask_3
[5]="?d?d?d?d?d"
37 mask_3
[6]="?d?d?d?d?d?d"
38 mask_3
[7]="?d?d?d?d?d?d?d"
39 mask_3
[8]="?d?d?d?d?d?d?d?d"
40 mask_3
[9]="?d?d?d?d?d?d?d?d?d"
41 mask_3
[10]="?d?d?d?d?d?d?d?d?d?d"
42 mask_3
[11]="?d?d?d?d?d?d?d?d?d?d?d"
43 mask_3
[12]="?d?d?d?d?d?d?d?d?d?d?d?d"
44 mask_3
[13]="?d?d?d?d?d?d?d?d?d?d?d?d?d"
45 mask_3
[14]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d"
46 mask_3
[15]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d"
47 mask_3
[16]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0"
48 mask_3
[17]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d00"
49 mask_3
[18]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d000"
50 mask_3
[19]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0000"
51 mask_3
[20]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d00000"
52 mask_3
[21]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d000000"
53 mask_3
[22]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0000000"
54 mask_3
[23]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d00000000"
55 mask_3
[24]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d000000000"
56 mask_3
[25]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0000000000"
57 mask_3
[26]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d00000000000"
58 mask_3
[27]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d000000000000"
59 mask_3
[28]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0000000000000"
60 mask_3
[29]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d00000000000000"
61 mask_3
[30]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d000000000000000"
62 mask_3
[31]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0000000000000000"
73 mask_6
[9]="?d?d?d?d?d"
74 mask_6
[10]="?d?d?d?d?d"
75 mask_6
[11]="?d?d?d?d?d?d"
76 mask_6
[12]="?d?d?d?d?d?d"
77 mask_6
[13]="?d?d?d?d?d?d?d"
78 mask_6
[14]="?d?d?d?d?d?d?d"
79 mask_6
[15]="?d?d?d?d?d?d?d?d"
80 mask_6
[16]="?d?d?d?d?d?d?d?d"
81 mask_6
[17]="?d?d?d?d?d?d?d?d0"
82 mask_6
[18]="?d?d?d?d?d?d?d?d0"
83 mask_6
[19]="?d?d?d?d?d?d?d?d00"
84 mask_6
[20]="?d?d?d?d?d?d?d?d00"
85 mask_6
[21]="?d?d?d?d?d?d?d?d000"
86 mask_6
[22]="?d?d?d?d?d?d?d?d000"
87 mask_6
[23]="?d?d?d?d?d?d?d?d0000"
88 mask_6
[24]="?d?d?d?d?d?d?d?d0000"
89 mask_6
[25]="?d?d?d?d?d?d?d?d00000"
90 mask_6
[26]="?d?d?d?d?d?d?d?d00000"
91 mask_6
[27]="?d?d?d?d?d?d?d?d000000"
92 mask_6
[28]="?d?d?d?d?d?d?d?d000000"
93 mask_6
[29]="?d?d?d?d?d?d?d?d0000000"
94 mask_6
[30]="?d?d?d?d?d?d?d?d0000000"
95 mask_6
[31]="?d?d?d?d?d?d?d?d00000000"
107 mask_7
[10]="?d?d?d?d?d"
108 mask_7
[11]="?d?d?d?d?d"
109 mask_7
[12]="?d?d?d?d?d?d"
110 mask_7
[13]="?d?d?d?d?d?d"
111 mask_7
[14]="?d?d?d?d?d?d?d"
112 mask_7
[15]="?d?d?d?d?d?d?d"
113 mask_7
[16]="?d?d?d?d?d?d?d?d"
114 mask_7
[17]="?d?d?d?d?d?d?d?d"
115 mask_7
[18]="?d?d?d?d?d?d?d?d0"
116 mask_7
[19]="?d?d?d?d?d?d?d?d0"
117 mask_7
[20]="?d?d?d?d?d?d?d?d00"
118 mask_7
[21]="?d?d?d?d?d?d?d?d00"
119 mask_7
[22]="?d?d?d?d?d?d?d?d000"
120 mask_7
[23]="?d?d?d?d?d?d?d?d000"
121 mask_7
[24]="?d?d?d?d?d?d?d?d0000"
122 mask_7
[25]="?d?d?d?d?d?d?d?d0000"
123 mask_7
[26]="?d?d?d?d?d?d?d?d00000"
124 mask_7
[27]="?d?d?d?d?d?d?d?d00000"
125 mask_7
[28]="?d?d?d?d?d?d?d?d000000"
126 mask_7
[29]="?d?d?d?d?d?d?d?d000000"
127 mask_7
[30]="?d?d?d?d?d?d?d?d0000000"
128 mask_7
[31]="?d?d?d?d?d?d?d?d0000000"
132 for element
in "${@:2}"; do
134 if [ "${element}" == "${1}" ]; then
145 if [ "${PACKAGE}" -eq 1 ]; then
147 echo "[ ${OUTD} ] > Generate tests for hash type $hash_type."
151 echo "[ ${OUTD} ] > Init test for hash type $hash_type."
155 rm -rf ${OUTD}/${hash_type}.sh ${OUTD}/${hash_type}_passwords.txt ${OUTD}/${hash_type}_hashes.txt
157 # create list of password and hashes of same type
158 grep " ${hash_type} '" ${OUTD}/all.sh > ${OUTD}/${hash_type}.sh
160 # create separate list of password and hashes
161 cat ${OUTD}/${hash_type}.sh | awk '{print $3}' > ${OUTD}/${hash_type}_passwords.txt
162 cat ${OUTD}/${hash_type}.sh | awk '{print $11}' | cut -d"'" -f2 > ${OUTD}/${hash_type}_hashes.txt
164 if [ "${hash_type}" -eq 10300 ]; then
165 cat ${OUTD}/${hash_type}.sh | cut -d' ' -f11- | cut -d"'" -f2 > ${OUTD}/${hash_type}_hashes.txt
169 rm -rf ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2
170 touch ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2
172 # foreach password entry split password in 2 (skip first entry, is len 1)
175 # minimum password length
179 if [ "${hash_type}" -eq 2500 ]; then
181 min_len=7 # means length 8, since we start with 0
185 while read -u 9 pass; do
187 if [ ${i} -gt 1 ]; then
189 # split password, 'i' is the len
193 # special case (passwords longer than expected)
196 if [ "${pass_len}" -gt 1 ]
199 p1=$((p1 + ${min_len}))
200 p0=$((p0 + ${min_len}))
202 if [ "${p1}" -gt ${pass_len} ]; then
209 # add splitted password to dicts
211 echo ${pass} | cut -c -${p0} >> ${OUTD}/${hash_type}_dict1
212 echo ${pass} | cut -c ${p1}- >> ${OUTD}/${hash_type}_dict2
219 done 9< ${OUTD}/${hash_type}_passwords.txt
223 if [ "${hash_type}" -eq 2500 ]; then
225 min_len=7 # means length 8, since we start with 0
229 # generate multiple pass/hash foreach len (2 to 8)
230 if [ ${MODE} -ge 1 ]; then
232 for ((i = 2; i < 9; i++)); do
234 rm -rf ${OUTD}/${hash_type}_multi_${i}.txt ${OUTD}/${hash_type}_passwords_multi_${i}.txt ${OUTD}/${hash_type}_hashes_multi_${i}.txt
235 rm -rf ${OUTD}/${hash_type}_dict1_multi_${i} ${OUTD}/${hash_type}_dict2_multi_${i}
236 touch ${OUTD}/${hash_type}_dict1_multi_${i} ${OUTD}/${hash_type}_dict2_multi_${i}
238 perl tools/test.pl single ${hash_type} ${i} > ${OUTD}/${hash_type}_multi_${i}.txt
240 cat ${OUTD}/${hash_type}_multi_${i}.txt | awk '{print $3}' > ${OUTD}/${hash_type}_passwords_multi_${i}.txt
241 cat ${OUTD}/${hash_type}_multi_${i}.txt | awk '{print $11}' | cut -d"'" -f2 > ${OUTD}/${hash_type}_hashes_multi_${i}.txt
243 if [ "${hash_type}" -eq 10300 ]; then
244 cat ${OUTD}/${hash_type}_multi_${i}.txt | cut -d' ' -f11- | cut -d"'" -f2 > ${OUTD}/${hash_type}_hashes_multi_${i}.txt
247 # split password, 'i' is the len
251 p0=$((p0 + ${min_len}))
252 p1=$((p1 + ${min_len}))
254 while read -u 9 pass; do
256 # add splitted password to dicts
257 echo ${pass} | cut -c -${p0} >> ${OUTD}/${hash_type}_dict1_multi_${i}
258 echo ${pass} | cut -c ${p1}- >> ${OUTD}/${hash_type}_dict2_multi_${i}
260 done 9< ${OUTD}/${hash_type}_passwords_multi_${i}.txt
273 if [ ${RET} -ne 0 ]; then
276 if contains ${hash_type} ${NEVER_CRACK_ALGOS}; then
278 echo "password not found
, cmdline
: ${CMD}" &>> ${OUTD}/logfull.txt
285 echo "timeout reached
, cmdline
: ${CMD}" &>> ${OUTD}/logfull.txt
290 if [ "${pass_only}" -eq 1 ]; then
291 echo "plains not found
in output
, cmdline
: ${CMD}" &>> ${OUTD}/logfull.txt
293 echo "hash:plains not matched
in output
, cmdline
: ${CMD}" &>> ${OUTD}/logfull.txt
299 echo "! unhandled
return code
${RET}, cmdline : ${CMD}" &>> ${OUTD}/logfull.txt
300 echo "! unhandled return code, see ${OUTD}/logfull.txt for details."
311 if ! contains
${hash_type} ${FILE_BASED_ALGOS}; then
318 if [ ${MODE} -ne 1 ]; then
325 echo "> Testing hash type $hash_type with attack mode 0, markov ${MARKOV}, single hash." &>> ${OUTD}/logfull.txt
329 if ! contains
${hash_type} ${TIMEOUT_ALGOS}; then
337 while read -u 9 line
; do
339 if [ "${i}" -ge ${max} ]; then
345 hash="$(echo "$line" | cut -d\' -f2)"
346 pass
="$(echo "$line" | cut -d' ' -f3)"
348 if [ -z "${hash}" ]; then
354 if [ "${file_only}" -eq 1 ]; then
356 temp_file
="${OUTD}/${hash_type}_filebased_only_temp.txt"
357 echo ${hash} | base64
-d > ${temp_file}
362 CMD
="echo -n "${pass}" | ./${BIN} ${OPTS} -a 0 -m ${hash_type} '${hash}'"
364 echo -n "[ len $((i + 1)) ] " &>> ${OUTD}/logfull.txt
366 output=$(echo -n "${pass}" | ./${BIN} ${OPTS} -a 0 -m ${hash_type} "${hash}" 2>&1)
370 echo "${output}" >> ${OUTD}/logfull.txt
372 if [ "${ret}" -eq 0 ]; then
374 if [ ${pass_only} -eq 1 ]; then
377 search="${hash}:${pass}"
380 echo "${output}" | grep -F "${search}" &> /dev/null
382 if [ "${?}" -ne 0 ]; then
394 done 9< ${OUTD}/${hash_type}.sh
398 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
402 elif [ "${e_to}" -ne 0 ]; then
408 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 0, Mode single ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
413 if [ ${MODE} -ne 0 ]; then
420 echo "> Testing hash type $hash_type with attack mode 0, markov ${MARKOV}, multi hash." &>> ${OUTD}/logfull.txt
422 hash_file=${OUTD}/${hash_type}_hashes.txt
424 # if file_only -> decode all base64 "hashes" and put them in the temporary file
426 if [ "${file_only}" -eq 1 ]; then
428 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
431 hash_file=${temp_file}
433 while read base64_hash; do
435 echo -n ${base64_hash} | base64 -d >> ${temp_file}
437 done < ${OUTD}/${hash_type}_hashes.txt
441 CMD="cat ${OUTD}/${hash_type}_passwords.txt | ./${BIN} ${OPTS} -a 0 -m ${hash_type} ${hash_file}"
443 output=$(cat ${OUTD}/${hash_type}_passwords.txt | ./${BIN} ${OPTS} -a 0 -m ${hash_type} ${hash_file} 2>&1)
447 echo "${output}" >> ${OUTD}/logfull.txt
449 if [ "${ret}" -eq 0 ]; then
453 while read -u 9 hash; do
455 pass=$(sed -n ${i}p ${OUTD}/${hash_type}_passwords.txt)
457 if [ ${pass_only} -eq 1 ]; then
460 search="${hash}:${pass}"
463 echo "${output}" | grep -F "${search}" &> /dev/null
465 if [ "${?}" -ne 0 ]; then
475 done 9< ${OUTD}/${hash_type}_hashes.txt
483 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
487 elif [ "${e_to}" -ne 0 ]; then
493 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 0, Mode multi ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
502 if ! contains ${hash_type} ${FILE_BASED_ALGOS}; then
509 if [ ${MODE} -ne 1 ]; then
516 echo "> Testing hash type $hash_type with attack mode 1, markov ${MARKOV}, single hash." &>> ${OUTD}/logfull.txt
518 while read -u 9 hash; do
520 if [ $i -gt 1 ]; then
522 if [ "${file_only}" -eq 1 ]; then
524 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
525 echo ${hash} | base64 -d > ${temp_file}
530 CMD="./${BIN} ${OPTS} -a 1 -m ${hash_type} '${hash}' ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2"
532 echo -n "[ len $i ] " &>> ${OUTD}/logfull.txt
534 output=$(./${BIN} ${OPTS} -a 1 -m ${hash_type} "${hash}" ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2 2>&1)
538 echo "${output}" >> ${OUTD}/logfull.txt
540 if [ "${ret}" -eq 0 ]; then
544 line_dict1=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict1)
545 line_dict2=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict2)
547 if [ ${pass_only} -eq 1 ]; then
548 search=":${line_dict1}${line_dict2}"
550 search="${hash}:${line_dict1}${line_dict2}"
553 echo "${output}" | grep -F "${search}" &> /dev/null
555 if [ "${?}" -ne 0 ]; then
569 done 9< ${OUTD}/${hash_type}_hashes.txt
573 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
577 elif [ "${e_to}" -ne 0 ]; then
583 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 1, Mode single ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
588 if [ ${MODE} -ne 0 ]; then
597 if [ ${hash_type} -eq 2500 ]; then
599 elif [ ${hash_type} -eq 5800 ]; then
601 elif [ ${hash_type} -eq 3000 ]; then
603 elif [ ${hash_type} -eq 2100 ]; then
605 elif [ ${hash_type} -eq 1500 ]; then
607 elif [ ${hash_type} -eq 7700 ]; then
609 elif [ ${hash_type} -eq 8500 ]; then
613 hash_file=${OUTD}/${hash_type}_multihash_combi.txt
615 tail -n ${offset} ${OUTD}/${hash_type}_hashes.txt > ${hash_file}
617 # if file_only -> decode all base64 "hashes" and put them in the temporary file
619 if [ "${file_only}" -eq 1 ]; then
621 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
624 hash_file=${temp_file}
626 while read base64_hash; do
628 echo -n ${base64_hash} | base64 -d >> ${temp_file}
630 done < ${OUTD}/${hash_type}_multihash_combi.txt
634 CMD="./${BIN} ${OPTS} -a 1 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2"
636 echo "> Testing hash type $hash_type with attack mode 1, markov ${MARKOV}, multi hash." &>> ${OUTD}/logfull.txt
638 output=$(./${BIN} ${OPTS} -a 1 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2 2>&1)
642 echo "${output}" >> ${OUTD}/logfull.txt
644 if [ "${ret}" -eq 0 ]; then
648 while read -u 9 hash; do
650 line_nr=$((offset - i))
652 line_dict1=$(tail -n ${line_nr} ${OUTD}/${hash_type}_dict1 | head -1)
653 line_dict2=$(tail -n ${line_nr} ${OUTD}/${hash_type}_dict2 | head -1)
655 if [ ${pass_only} -eq 1 ]; then
656 search=":${line_dict1}${line_dict2}"
658 search="${hash}:${line_dict1}${line_dict2}"
661 echo "${output}" | grep -F "${search}" &> /dev/null
663 if [ "${?}" -ne 0 ]; then
673 done 9< ${OUTD}/${hash_type}_multihash_combi.txt
681 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
685 elif [ "${e_to}" -ne 0 ]; then
691 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 1, Mode multi ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
700 if ! contains ${hash_type} ${FILE_BASED_ALGOS}; then
707 if [ ${MODE} -ne 1 ]; then
714 echo "> Testing hash type $hash_type with attack mode 3, markov ${MARKOV}, single hash." &>> ${OUTD}/logfull.txt
719 # some algos have a minimum password length
721 if [ "${hash_type}" -eq 2500 ];then
730 while read -u 9 hash; do
732 if [ "${i}" -gt 6 ]; then
734 if ! contains ${hash_type} ${TIMEOUT_ALGOS}; then
742 if [ "${file_only}" -eq 1 ]; then
744 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt"
745 echo ${hash} | base64 -d > ${temp_file}
750 mask=${mask_3[$((i + ${mask_offset}))]}
752 # modify "default" mask if needed (and set custom charset to reduce keyspace)
754 if [ "${hash_type}" -eq 2500 ]; then
756 pass=$(sed -n ${i}p ${OUTD}/${hash_type}_passwords.txt)
760 # replace the first x positions in the mask with ?d's
762 # first: remove first i (== amount) chars
764 mask
=$
(echo ${mask} | cut
-b $
((i
+ 1))-)
768 for i
in $
(seq 1 ${i}); do
776 CMD
="./${BIN} ${OPTS} -a 3 -m ${hash_type} '${hash}' ${mask}"
778 echo -n "[ len $i ] " &>> ${OUTD}/logfull.txt
780 output
=$
(.
/${BIN} ${OPTS} -a 3 -m ${hash_type} "${hash}" ${mask} 2>&1)
784 echo "${output}" >> ${OUTD}/logfull.txt
786 if [ "${ret}" -eq 0 ]; then
788 line_dict
=$
(sed -n ${i}p ${OUTD}/${hash_type}_passwords.txt
)
790 if [ ${pass_only} -eq 1 ]; then
791 search
=":${line_dict}"
793 search
="${hash}:${line_dict}"
796 echo "${output}" |
grep -F "${search}" &> /dev
/null
798 if [ "${?}" -ne 0 ]; then
808 if [ $i -eq ${max} ]; then break; fi
812 done 9< ${OUTD}/${hash_type}_hashes.txt
816 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
820 elif [ "${e_to}" -ne 0 ]; then
826 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 3, Mode single ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
831 if [ ${MODE} -ne 0 ]; then
840 if ! contains
${hash_type} ${TIMEOUT_ALGOS}; then
848 if [ "${hash_type}" -eq 2500 ]; then
855 hash_file
=${OUTD}/${hash_type}_multihash_bruteforce.txt
857 head -n $
((increment_max
- ${increment_min} + 1)) ${OUTD}/${hash_type}_hashes.txt > ${hash_file}
859 # if file_only -> decode all base64 "hashes" and put them in the temporary file
861 if [ "${file_only}" -eq 1 ]; then
863 temp_file
="${OUTD}/${hash_type}_filebased_only_temp.txt"
866 hash_file
=${temp_file}
868 while read base64_hash
; do
870 echo -n ${base64_hash} | base64
-d >> ${temp_file}
872 done < ${OUTD}/${hash_type}_multihash_bruteforce.txt
879 # modify "default" mask if needed (and set custom charset to reduce keyspace)
881 if [ "${hash_type}" -eq 2500 ]; then
883 mask
="?d?d?d?d?d?1?2?3?4"
890 # check positions (here we assume that mask is always composed of non literal chars
891 # i.e. something like ?d?l?u?s?1 is possible, but ?d?dsuffix not
892 charset_1_pos
=$
(expr index
"${mask}" 1)
893 charset_2_pos
=$
(expr index
"${mask}" 2)
894 charset_3_pos
=$
(expr index
"${mask}" 3)
895 charset_4_pos
=$
(expr index
"${mask}" 4)
897 # divide each charset position by 2 since each of them occupies 2 positions in the mask
899 charset_1_pos
=$
((charset_1_pos
/ 2))
900 charset_2_pos
=$
((charset_2_pos
/ 2))
901 charset_3_pos
=$
((charset_3_pos
/ 2))
902 charset_4_pos
=$
((charset_4_pos
/ 2))
906 while read -u 9 hash; do
908 pass
=$
(sed -n ${i}p ${OUTD}/${hash_type}_passwords.txt
)
911 char
=$
(echo "${pass}" | cut
-b ${charset_1_pos})
912 charset_1
=$
(echo -e "${charset_1}\n${char}")
915 char
=$
(echo "${pass}" | cut
-b ${charset_2_pos})
916 charset_2
=$
(echo -e "${charset_2}\n${char}")
919 char
=$
(echo "${pass}" | cut
-b ${charset_3_pos})
920 charset_3
=$
(echo -e "${charset_3}\n${char}")
923 char
=$
(echo "${pass}" | cut
-b ${charset_4_pos})
924 charset_4
=$
(echo -e "${charset_4}\n${char}")
928 done 9< ${OUTD}/${hash_type}_multihash_bruteforce.txt
930 # just make sure that all custom charset fields are initialized
932 if [ -z "${charset_1}" ]; then
938 if [ -z "${charset_2}" ]; then
944 if [ -z "${charset_3}" ]; then
950 if [ -z "${charset_4}" ]; then
956 # unique and remove new lines
958 charset_1
=$
(echo "${charset_1}" |
sort -u |
tr -d '\n')
959 charset_2
=$
(echo "${charset_2}" |
sort -u |
tr -d '\n')
960 charset_3
=$
(echo "${charset_3}" |
sort -u |
tr -d '\n')
961 charset_4
=$
(echo "${charset_4}" |
sort -u |
tr -d '\n')
963 custom_charsets
="-1 ${charset_1} -2 ${charset_2} -3 ${charset_3} -4 ${charset_4}"
966 CMD
="./${BIN} ${OPTS} -a 3 -m ${hash_type} --increment --increment-min ${increment_min} --increment-max ${increment_max} ${custom_charsets} ${hash_file} ${mask} "
968 echo "> Testing hash type $hash_type with attack mode 3, markov ${MARKOV}, multi hash." &>> ${OUTD}/logfull.txt
970 output
=$
(.
/${BIN} ${OPTS} -a 3 -m ${hash_type} --increment --increment-min ${increment_min} --increment-max ${increment_max} ${custom_charsets} ${hash_file} ${mask} 2>&1)
974 echo "${output}" >> ${OUTD}/logfull.txt
976 if [ "${ret}" -eq 0 ]; then
980 while read -u 9 hash; do
982 pass
=$
(sed -n ${i}p ${OUTD}/${hash_type}_passwords.txt
)
984 if [ ${pass_only} -eq 1 ]; then
987 search
="${hash}:${pass}"
990 echo "${output}" |
grep -F "${search}" &> /dev
/null
992 if [ "${?}" -ne 0 ]; then
1002 done 9< ${OUTD}/${hash_type}_multihash_bruteforce.txt
1010 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
1014 elif [ "${e_to}" -ne 0 ]; then
1020 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 3, Mode multi ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
1029 if ! contains
${hash_type} ${FILE_BASED_ALGOS}; then
1036 if [ ${MODE} -ne 1 ]; then
1043 echo "> Testing hash type $hash_type with attack mode 6, markov ${MARKOV}, single hash." &>> ${OUTD}/logfull.txt
1049 if [ "${hash_type}" -eq 2500 ]; then
1055 while read -u 9 hash; do
1057 if [ "${i}" -gt 6 ]; then
1059 if ! contains
${hash_type} ${TIMEOUT_ALGOS}; then
1067 if [ $i -gt 1 ]; then
1069 if [ "${file_only}" -eq 1 ]; then
1071 temp_file
="${OUTD}/${hash_type}_filebased_only_temp.txt"
1072 echo ${hash} | base64
-d > ${temp_file}
1077 CMD
="./${BIN} ${OPTS} -a 6 -m ${hash_type} '${hash}' ${OUTD}/${hash_type}_dict1 ${mask_6[$i]}"
1079 echo -n "[ len $i ] " &>> ${OUTD}/logfull.txt
1081 output
=$
(.
/${BIN} ${OPTS} -a 6 -m ${hash_type} "${hash}" ${OUTD}/${hash_type}_dict1 ${mask_6[$i]} 2>&1)
1085 echo "${output}" >> ${OUTD}/logfull.txt
1087 if [ "${ret}" -eq 0 ]; then
1091 line_dict1
=$
(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict1
)
1092 line_dict2
=$
(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict2
)
1094 if [ ${pass_only} -eq 1 ]; then
1095 search
=":${line_dict1}${line_dict2}"
1097 search
="${hash}:${line_dict1}${line_dict2}"
1100 echo "${output}" |
grep -F "${search}" &> /dev
/null
1102 if [ "${?}" -ne 0 ]; then
1114 if [ "${i}" -eq ${max} ]; then break; fi
1118 done 9< ${OUTD}/${hash_type}_hashes.txt
1122 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
1126 elif [ "${e_to}" -ne 0 ]; then
1132 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 6, Mode single ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
1137 if [ ${MODE} -ne 0 ]; then
1146 if [ ${hash_type} -eq 2500 ]; then
1148 elif [ ${hash_type} -eq 3000 ]; then
1150 elif [ ${hash_type} -eq 7700 ]; then
1152 elif [ ${hash_type} -eq 8500 ]; then
1156 if ! contains
${hash_type} ${TIMEOUT_ALGOS}; then
1160 if [ "${hash_type}" -eq 3200 ]; then
1168 for ((i
= 2; i
< ${max}; i
++)); do
1170 hash_file
=${OUTD}/${hash_type}_hashes_multi_${i}.txt
1172 # if file_only -> decode all base64 "hashes" and put them in the temporary file
1174 if [ "${file_only}" -eq 1 ]; then
1176 temp_file
="${OUTD}/${hash_type}_filebased_only_temp.txt"
1179 hash_file
=${temp_file}
1181 while read base64_hash
; do
1183 echo -n ${base64_hash} | base64
-d >> ${temp_file}
1185 done < ${OUTD}/${hash_type}_hashes_multi_${i}.txt
1189 CMD
="./${BIN} ${OPTS} -a 6 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1_multi_${i} ${mask_6[$i]}"
1191 echo "> Testing hash type $hash_type with attack mode 6, markov ${MARKOV}, multi hash with word len ${i}." &>> ${OUTD}/logfull.txt
1193 output=$(./${BIN} ${OPTS} -a 6 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1_multi_${i} ${mask_6[$i]} 2>&1)
1197 echo "${output}" >> ${OUTD}/logfull.txt
1199 if [ "${ret}" -eq 0 ]; then
1203 while read -u 9 hash; do
1205 line_dict1=$(sed -n ${j}p ${OUTD}/${hash_type}_dict1_multi_${i})
1206 line_dict2=$(sed -n ${j}p ${OUTD}/${hash_type}_dict2_multi_${i})
1208 if [ ${pass_only} -eq 1 ]; then
1209 search=":${line_dict1}${line_dict2}"
1211 search="${hash}:${line_dict1}${line_dict2}"
1214 echo "${output}" | grep -F "${search}" &> /dev/null
1216 if [ "${?}" -ne 0 ]; then
1226 done 9< ${OUTD}/${hash_type}_hashes_multi_${i}.txt
1236 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
1240 elif [ "${e_to}" -ne 0 ]; then
1246 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 6, Mode multi ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout
"
1255 if ! contains ${hash_type} ${FILE_BASED_ALGOS}; then
1262 if [ ${MODE} -ne 1 ]; then
1269 echo "> Testing
hash type $hash_type with attack mode
7, markov
${MARKOV}, single
hash.
" &>> ${OUTD}/logfull.txt
1273 if [ "${hash_type}" -eq 2500 ]; then
1281 while read -u 9 hash; do
1283 if [ $i -gt 1 ]; then
1285 if [ "${file_only}" -eq 1 ]; then
1287 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt
"
1288 echo ${hash} | base64 -d > ${temp_file}
1295 # adjust mask if needed
1297 if [ "${hash_type}" -eq 2500 ]; then
1301 pass_part_1=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict1)
1302 pass_part_2=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict2)
1304 pass_part_2_len=${#pass_part_2}
1306 pass=${pass_part_1}${pass_part_2}
1309 # add first x chars of password to mask and append the (old) mask
1312 mask_len=$((mask_len / 2))
1314 mask_prefix=$(echo ${pass} | cut -b -$((pass_len - ${mask_len} - ${pass_part_2_len})))
1315 mask=${mask_prefix}${mask}
1319 CMD=".
/${BIN} ${OPTS} -a 7 -m ${hash_type} '${hash}' ${mask} ${OUTD}/${hash_type}_dict2
"
1321 echo -n "[ len
$i ] " &>> ${OUTD}/logfull.txt
1323 output=$(./${BIN} ${OPTS} -a 7 -m ${hash_type} "${hash}" ${mask} ${OUTD}/${hash_type}_dict2 2>&1)
1327 echo "${output}" >> ${OUTD}/logfull.txt
1329 if [ "${ret}" -eq 0 ]; then
1333 line_dict1=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict1)
1334 line_dict2=$(sed -n ${line_nr}p ${OUTD}/${hash_type}_dict2)
1336 if [ ${pass_only} -eq 1 ]; then
1337 search=":${line_dict1}${line_dict2}"
1339 search="${hash}:${line_dict1}${line_dict2}"
1342 echo "${output}" | grep -F "${search}" &> /dev/null
1344 if [ "${?}" -ne 0 ]; then
1356 if [ $i -eq ${max} ]; then break; fi
1360 done 9< ${OUTD}/${hash_type}_hashes.txt
1364 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
1368 elif [ "${e_to}" -ne 0 ]; then
1374 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 7, Mode single ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout
"
1379 if [ ${MODE} -ne 0 ]; then
1388 if [ ${hash_type} -eq 2500 ]; then
1390 elif [ ${hash_type} -eq 3000 ]; then
1392 elif [ ${hash_type} -eq 7700 ]; then
1394 elif [ ${hash_type} -eq 8500 ]; then
1398 if ! contains ${hash_type} ${TIMEOUT_ALGOS}; then
1402 if [ "${hash_type}" -eq 3200 ]; then
1410 for ((i = 2; i < ${max}; i++)); do
1412 hash_file=${OUTD}/${hash_type}_hashes_multi_${i}.txt
1413 dict_file=${OUTD}/${hash_type}_dict2_multi_${i}
1417 # if file_only -> decode all base64 "hashes
" and put them in the temporary file
1419 if [ "${file_only}" -eq 1 ]; then
1421 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt
"
1424 hash_file=${temp_file}
1426 while read base64_hash; do
1428 echo -n ${base64_hash} | base64 -d >> ${temp_file}
1430 done < ${OUTD}/${hash_type}_hashes_multi_${i}.txt
1432 # a little hack: since we don't want to have a very large mask (and wpa has minimum length of 8),
1433 # we need to create a temporary dict file on-the-fly and use it like this: [small mask] [long(er) words in dict]
1435 dict_file=${OUTD}/${hash_type}_dict2_multi_${i}_longer
1439 mask_len=$((mask_len / 2))
1443 while read -u 9 hash; do
1445 pass_part_1=$(sed -n ${j}p ${OUTD}/${hash_type}_dict1_multi_${i})
1446 pass_part_2=$(sed -n ${j}p ${OUTD}/${hash_type}_dict2_multi_${i})
1448 pass="${pass_part_1}${pass_part_2}"
1450 pass_suffix=$(echo "${pass}" | cut -b $((mask_len + 1))-)
1452 echo "${pass_suffix}" >> ${dict_file}
1456 done 9< ${OUTD}/${hash_type}_hashes_multi_${i}.txt
1460 CMD=".
/${BIN} ${OPTS} -a 7 -m ${hash_type} ${hash_file} ${mask} ${dict_file}"
1462 echo "> Testing
hash type $hash_type with attack mode
7, markov
${MARKOV}, multi hash with word len ${i}." &>> ${OUTD}/logfull.txt
1464 output
=$
(.
/${BIN} ${OPTS} -a 7 -m ${hash_type} ${hash_file} ${mask} ${dict_file} 2>&1)
1468 echo "${output}" >> ${OUTD}/logfull.txt
1470 if [ "${ret}" -eq 0 ]; then
1474 while read -u 9 hash; do
1476 line_dict1
=$
(sed -n ${j}p ${OUTD}/${hash_type}_dict1_multi_${i})
1477 line_dict2
=$
(sed -n ${j}p ${OUTD}/${hash_type}_dict2_multi_${i})
1479 if [ ${pass_only} -eq 1 ]; then
1480 search
=":${line_dict1}${line_dict2}"
1482 search
="${hash}:${line_dict1}${line_dict2}"
1485 echo "${output}" |
grep -F "${search}" &> /dev
/null
1487 if [ "${?}" -ne 0 ]; then
1497 done 9< ${OUTD}/${hash_type}_hashes_multi_${i}.txt
1507 if [ "${e_nf}" -ne 0 -o "${e_nm}" -ne 0 ]; then
1511 elif [ "${e_to}" -ne 0 ]; then
1517 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 7, Mode multi ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout"
1525 > Usage : ${0} <options>
1529 -t Select test mode :
1530 'single' => single hash (default)
1531 'multi' => multi hash
1532 'all' => single and multi hash
1534 -m Select hash type :
1535 'all' => all hash type supported
1536 (int) => hash type integer code (default : 0)
1538 -a Select attack mode :
1539 'all' => all attack modes
1540 (int) => attack mode integer code (default : 0)
1542 -x Select cpu architecture :
1543 '32' => 32 bit architecture
1544 '64' => 64 bit architecture (default)
1546 -o Select operating system :
1547 'win' => windows operating system (use .exe file extension etc)
1548 'linux' => *nix based operating systems (.bin for binaries)
1549 'osx' => mac osx operating systems (.app for binaries)
1551 -c Disables markov-chains
1553 -p Package the tests into a .7z file
1555 -d Use this folder as input/output folder for packaged tests
1556 (string) => path to folder
1572 while getopts "t:m:a:b:hcpd:x:o:" opt
; do
1576 if [ ${OPTARG} == "single" ]; then
1578 elif [ ${OPTARG} == "multi" ]; then
1580 elif [ ${OPTARG} == "all" ]; then
1588 if [ ${OPTARG} == "all" ]; then
1596 if [ ${OPTARG} == "all" ]; then
1598 elif [ ${OPTARG} == "0" ]; then
1600 elif [ ${OPTARG} == "1" ]; then
1602 elif [ ${OPTARG} == "3" ]; then
1604 elif [ ${OPTARG} == "6" ]; then
1606 elif [ ${OPTARG} == "7" ]; then
1614 OPTS
="${OPTS} --markov-disable"
1619 PACKAGE_FOLDER
=$
( echo ${OPTARG} |
sed 's!/$!!g' )
1627 if [ ${OPTARG} == "32" ]; then
1629 elif [ ${OPTARG} == "64" ]; then
1637 if [ ${OPTARG} == "win" ]; then
1639 elif [ ${OPTARG} == "linux" ]; then
1641 elif [ ${OPTARG} == "osx" ]; then
1659 if [ -n "${ARCHITECTURE}" ]; then
1661 BIN
="${BIN}${ARCHITECTURE}"
1665 if [ -n "${EXTENSION}" ]; then
1667 BIN
="${BIN}.${EXTENSION}"
1671 if [ -n "${PACKAGE_FOLDER}" ]; then
1673 if [ ! -e "${PACKAGE_FOLDER}" ]; then
1674 echo "! folder '${PACKAGE_FOLDER}' does not exist"
1680 if [ "${PACKAGE}" -eq 0 -o -z "${PACKAGE_FOLDER}" ]; then
1682 # check existence of binary
1683 if [ ! -e "${BIN}" ]; then
1684 echo "! ${BIN} not found, please build binary before run test."
1688 # filter by hash_type
1689 if [ ${HT} -ne 65535 ]; then
1693 for hash_type
in $
(echo ${HASH_TYPES}); do
1695 if [ ${HT} -ne ${hash_type} ]; then continue; fi
1703 if [ ${check} -ne 1 ]; then
1704 echo "! invalid hash type selected ..."
1710 if [ -z "${PACKAGE_FOLDER}" ]; then
1715 # generate random test entry
1716 if [ ${HT} -eq 65535 ]; then
1717 perl tools
/test.pl single
> ${OUTD}/all.sh
1719 perl tools
/test.pl single
${HT} > ${OUTD}/all.sh
1724 OUTD
=${PACKAGE_FOLDER}
1728 rm -rf ${OUTD}/logfull.txt
&& touch ${OUTD}/logfull.txt
1730 # populate array of hash types where we only should check if pass is in output (not both hash:pass)
1731 IFS
=';' read -ra PASS_ONLY
<<< "${MATCH_PASS_ONLY}"
1732 IFS
=';' read -ra TIMEOUT_ALGOS
<<< "${SLOW_ALGOS}"
1734 IFS
=';' read -ra NEVER_CRACK_ALGOS
<<< "${NEVER_CRACK}"
1736 # for these particular algos we need to save the output to a temporary file
1737 IFS
=';' read -ra FILE_BASED_ALGOS
<<< "${HASHFILE_ONLY}"
1739 for hash_type
in $
(echo $HASH_TYPES); do
1741 if [[ ${HT} -ne 65535 ]] && [[ ${HT} -ne ${hash_type} ]]; then continue; fi
1743 if [ -z "${PACKAGE_FOLDER}" ]; then
1750 echo "[ ${OUTD} ] > Run packaged test for hash type $hash_type."
1754 if [ "${PACKAGE}" -eq 0 ]; then
1756 # should we check only the pass?
1757 contains
${hash_type} ${PASS_ONLY}
1760 contains
${hash_type} ${SLOW_ALGOS}
1763 if [[ ${hash_type} -eq 400 ]]; then
1764 # we use phpass as slow hash for testing the AMP kernel
1768 if [[ ${IS_SLOW} -eq 1 ]]; then
1770 # run attack mode 0 (stdin)
1771 if [[ ${ATTACK} -eq 65535 ]] ||
[[ ${ATTACK} -eq 0 ]]; then attack_0
; fi
1774 # run attack mode 0 (stdin)
1775 if [[ ${ATTACK} -eq 65535 ]] ||
[[ ${ATTACK} -eq 0 ]]; then attack_0
; fi
1777 # run attack mode 1 (combinator)
1778 if [[ ${ATTACK} -eq 65535 ]] ||
[[ ${ATTACK} -eq 1 ]]; then attack_1
; fi
1780 # run attack mode 3 (bruteforce)
1781 if [[ ${ATTACK} -eq 65535 ]] ||
[[ ${ATTACK} -eq 3 ]]; then attack_3
; fi
1783 # run attack mode 6 (dict+mask)
1784 if [[ ${ATTACK} -eq 65535 ]] ||
[[ ${ATTACK} -eq 6 ]]; then attack_6
; fi
1786 # run attack mode 7 (mask+dict)
1787 if [[ ${ATTACK} -eq 65535 ]] ||
[[ ${ATTACK} -eq 7 ]]; then attack_7
; fi
1795 OUTD
=${PACKAGE_FOLDER}
1800 if [ "${PACKAGE}" -eq 0 ]; then
1802 cat -A ${OUTD}/logfull.txt |
sed -e 's/\^M \^M//g' |
sed -e 's/\$$//g' > ${OUTD}/test_report.log
1806 rm -rf ${OUTD}/logfull.txt
1808 if [ "${PACKAGE}" -eq 1 ]; then
1810 echo "[ ${OUTD} ] > Generate package ${OUTD}/${OUTD}.7z"
1812 cp "${BASH_SOURCE[0]}" ${OUTD}/test.sh
1814 # if we package from a given folder, we need to check if e.g. the files needed for multi mode are there
1816 if [ -n "${PACKAGE_FOLDER}" ]; then
1820 ls "${PACKAGE_FOLDER}"/*multi
* &> /dev
/null
1829 HT
=$
(grep -o -- "-m *[0-9]*" ${PACKAGE_FOLDER}/all.sh |
sort -u |
sed 's/-m //' 2> /dev
/null
)
1831 if [ -n "${HT}" ]; then
1833 HT_COUNT
=$
(echo "${HT}" |
wc -l)
1835 if [ "${HT_COUNT}" -gt 1 ]; then
1843 #ATTACK=65535 # more appropriate ?
1846 # for convenience: 'run package' is default action for packaged test.sh ( + add other defaults too )
1848 sed -i -e 's/^\(PACKAGE_FOLDER\)=""/\1="$( echo "${BASH_SOURCE[0]}" | sed \"s!test.sh\\$!!\" )"/' \
1849 -e "s/^\(HT\)=0/\1=${HT}/" \
1850 -e "s/^\(MODE\)=0/\1=${MODE}/" \
1851 -e "s/^\(ATTACK\)=0/\1=${ATTACK}/" \
1854 ${PACKAGE_CMD} ${OUTD}/${OUTD}.7z ${OUTD}/ &> /dev
/null