1#!/usr/bin/env bash 2 3## 4## Author......: See docs/credits.txt 5## License.....: MIT 6## 7 8OPTS="--quiet --potfile-disable --runtime 400 --hwmon-disable" 9 10TDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 11 12# List of TrueCrypt modes which have test containers 13TC_MODES="6211 6212 6213 6221 6222 6223 6231 6232 6233 6241 6242 6243" 14 15# List of VeraCrypt modes which have test containers 16VC_MODES="13711 13712 13713 13721 13722 13723 13731 13732 13733 13741 13742 13743 13751 13752 13753 13761 13762 13763 13771 13772 13773 13781 13782 13783" 17 18# List of modes which either are OPTS_TYPE_PT_NEVERCRACK or produce collisions 19NEVER_CRACK="9720 9820 14900 18100" 20 21# List of modes which return a different output hash format than the input hash format 22NOCHECK_ENCODING="16800 22000" 23 24# LUKS mode has test containers 25LUKS_MODE="14600" 26 27# Cryptoloop mode which have test containers 28CL_MODES="14511 14512 14513 14521 14522 14523 14531 14532 14533 14541 14542 14543 14551 14552 14553" 29 30# missing hash types: 5200 31 32HASH_TYPES=$(ls "${TDIR}"/test_modules/*.pm | sed -E 's/.*m0*([0-9]+).pm/\1/') 33HASH_TYPES="${HASH_TYPES} ${TC_MODES} ${VC_MODES} ${LUKS_MODE} ${CL_MODES}" 34HASH_TYPES=$(echo -n "${HASH_TYPES}" | tr ' ' '\n' | sort -u -n | tr '\n' ' ') 35 36VECTOR_WIDTHS="1 2 4 8 16" 37 38HASHFILE_ONLY=$(grep -l OPTS_TYPE_BINARY_HASHFILE "${TDIR}"/../src/modules/module_*.c | sed -E 's/.*module_0*([0-9]+).c/\1/' | tr '\n' ' ') 39SLOW_ALGOS=$(grep -l ATTACK_EXEC_OUTSIDE_KERNEL "${TDIR}"/../src/modules/module_*.c | sed -E 's/.*module_0*([0-9]+).c/\1/' | tr '\n' ' ') 40 41OUTD="test_$(date +%s)" 42 43PACKAGE_CMD="7z a" 44PACKAGE_FOLDER="" 45 46EXTRACT_CMD="7z x" 47 48mask_3[0]="" 49mask_3[1]="?d" 50mask_3[2]="?d?d" 51mask_3[3]="?d?d?d" 52mask_3[4]="?d?d?d?d" 53mask_3[5]="?d?d?d?d?d" 54mask_3[6]="?d?d?d?d?d?d" 55mask_3[7]="?d?d?d?d?d?d?d" 56mask_3[8]="?d?d?d?d?d?d?d?d" 57mask_3[9]="?d?d?d?d?d?d?d?d?d" 58mask_3[10]="?d?d?d?d?d?d?d?d?d?d" 59mask_3[11]="?d?d?d?d?d?d?d?d?d?d?d" 60mask_3[12]="?d?d?d?d?d?d?d?d?d?d?d?d" 61mask_3[13]="?d?d?d?d?d?d?d?d?d?d?d?d?d" 62mask_3[14]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d" 63mask_3[15]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d" 64mask_3[16]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0" 65mask_3[17]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d00" 66mask_3[18]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d000" 67mask_3[19]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0000" 68mask_3[20]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d00000" 69mask_3[21]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d000000" 70mask_3[22]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0000000" 71mask_3[23]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d00000000" 72mask_3[24]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d000000000" 73mask_3[25]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0000000000" 74mask_3[26]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d00000000000" 75mask_3[27]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d000000000000" 76mask_3[28]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0000000000000" 77mask_3[29]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d00000000000000" 78mask_3[30]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d000000000000000" 79mask_3[31]="?d?d?d?d?d?d?d?d?d?d?d?d?d?d?d0000000000000000" 80 81mask_6[0]="" 82mask_6[1]="" 83mask_6[2]="?d" 84mask_6[3]="?d?d" 85mask_6[4]="?d?d" 86mask_6[5]="?d?d?d" 87mask_6[6]="?d?d?d" 88mask_6[7]="?d?d?d?d" 89mask_6[8]="?d?d?d?d" 90mask_6[9]="?d?d?d?d?d" 91mask_6[10]="?d?d?d?d?d" 92mask_6[11]="?d?d?d?d?d?d" 93mask_6[12]="?d?d?d?d?d?d" 94mask_6[13]="?d?d?d?d?d?d?d" 95mask_6[14]="?d?d?d?d?d?d?d" 96mask_6[15]="?d?d?d?d?d?d?d?d" 97mask_6[16]="?d?d?d?d?d?d?d?d" 98mask_6[17]="?d?d?d?d?d?d?d?d0" 99mask_6[18]="?d?d?d?d?d?d?d?d0" 100mask_6[19]="?d?d?d?d?d?d?d?d00" 101mask_6[20]="?d?d?d?d?d?d?d?d00" 102mask_6[21]="?d?d?d?d?d?d?d?d000" 103mask_6[22]="?d?d?d?d?d?d?d?d000" 104mask_6[23]="?d?d?d?d?d?d?d?d0000" 105mask_6[24]="?d?d?d?d?d?d?d?d0000" 106mask_6[25]="?d?d?d?d?d?d?d?d00000" 107mask_6[26]="?d?d?d?d?d?d?d?d00000" 108mask_6[27]="?d?d?d?d?d?d?d?d000000" 109mask_6[28]="?d?d?d?d?d?d?d?d000000" 110mask_6[29]="?d?d?d?d?d?d?d?d0000000" 111mask_6[30]="?d?d?d?d?d?d?d?d0000000" 112mask_6[31]="?d?d?d?d?d?d?d?d00000000" 113 114mask_7[0]="" 115mask_7[1]="" 116mask_7[2]="?d" 117mask_7[3]="?d" 118mask_7[4]="?d?d" 119mask_7[5]="?d?d" 120mask_7[6]="?d?d?d" 121mask_7[7]="?d?d?d" 122mask_7[8]="?d?d?d?d" 123mask_7[9]="?d?d?d?d" 124mask_7[10]="?d?d?d?d?d" 125mask_7[11]="?d?d?d?d?d" 126mask_7[12]="?d?d?d?d?d?d" 127mask_7[13]="?d?d?d?d?d?d" 128mask_7[14]="?d?d?d?d?d?d?d" 129mask_7[15]="?d?d?d?d?d?d?d" 130mask_7[16]="?d?d?d?d?d?d?d?d" 131mask_7[17]="?d?d?d?d?d?d?d?d" 132mask_7[18]="?d?d?d?d?d?d?d?d0" 133mask_7[19]="?d?d?d?d?d?d?d?d0" 134mask_7[20]="?d?d?d?d?d?d?d?d00" 135mask_7[21]="?d?d?d?d?d?d?d?d00" 136mask_7[22]="?d?d?d?d?d?d?d?d000" 137mask_7[23]="?d?d?d?d?d?d?d?d000" 138mask_7[24]="?d?d?d?d?d?d?d?d0000" 139mask_7[25]="?d?d?d?d?d?d?d?d0000" 140mask_7[26]="?d?d?d?d?d?d?d?d00000" 141mask_7[27]="?d?d?d?d?d?d?d?d00000" 142mask_7[28]="?d?d?d?d?d?d?d?d000000" 143mask_7[29]="?d?d?d?d?d?d?d?d000000" 144mask_7[30]="?d?d?d?d?d?d?d?d0000000" 145mask_7[31]="?d?d?d?d?d?d?d?d0000000" 146 147# Array lookup 148# $1: value 149# $2: array 150# Returns 0 (SUCCESS) if the value is found, 1 otherwise 151function is_in_array() 152{ 153 for e in "${@:2}"; do 154 [ "$e" = "$1" ] && return 0 155 done 156 return 1 157} 158 159function init() 160{ 161 if [ "${PACKAGE}" -eq 1 ]; then 162 echo "[ ${OUTD} ] > Generate tests for hash type $hash_type." 163 else 164 echo "[ ${OUTD} ] > Init test for hash type $hash_type." 165 fi 166 167 rm -rf "${OUTD}/${hash_type}.sh" "${OUTD}/${hash_type}_passwords.txt" "${OUTD}/${hash_type}_hashes.txt" 168 169 # Exclude TrueCrypt, VeraCrypt and CryptoLoop testing modes 170 if is_in_array "${hash_type}" ${TC_MODES}; then 171 return 0 172 fi 173 if is_in_array "${hash_type}" ${VC_MODES}; then 174 return 0 175 fi 176 if is_in_array "${hash_type}" ${CL_MODES}; then 177 return 0 178 fi 179 180 if [ "${hash_type}" -eq ${LUKS_MODE} ]; then 181 182 luks_tests_folder="${TDIR}/luks_tests/" 183 184 if [ ! -d "${luks_tests_folder}" ]; then 185 mkdir -p "${luks_tests_folder}" 186 fi 187 188 luks_first_test_file="${luks_tests_folder}/hashcat_ripemd160_aes_cbc-essiv_128.luks" 189 190 if [ ! -f "${luks_first_test_file}" ]; then 191 luks_tests="hashcat_luks_testfiles.7z" 192 luks_tests_url="https://hashcat.net/misc/example_hashes/${luks_tests}" 193 194 cd "${TDIR}" || exit 195 196 # if the file already exists, but was not successfully extracted, we assume it's a broken 197 # downloaded file and therefore it should be deleted 198 199 if [ -f "${luks_tests}" ]; then 200 rm -f "${luks_tests}" 201 fi 202 203 echo "" 204 echo "ATTENTION: the luks test files (for -m ${hash_type}) are currently missing on your system." 205 echo "They will be fetched from ${luks_tests_url}" 206 echo "Note: this needs to be done only once and could take a little bit to download/extract." 207 echo "These luks test files are not shipped directly with hashcat because the file sizes are" 208 echo "particularily large and therefore a bandwidth burner for users who do not run these tests." 209 echo "" 210 211 # download: 212 213 if ! wget -q "${luks_tests_url}" >/dev/null 2>/dev/null; then 214 cd - >/dev/null 215 echo "ERROR: Could not fetch the luks test files from this url: ${luks_tests_url}" 216 exit 1 217 fi 218 219 # extract: 220 221 ${EXTRACT_CMD} "${luks_tests}" >/dev/null 2>/dev/null 222 223 # cleanup: 224 225 rm -f "${luks_tests}" 226 cd - >/dev/null || exit 227 228 # just to be very sure, check again that (one of) the files now exist: 229 230 if [ ! -f "${luks_first_test_file}" ]; then 231 echo "ERROR: downloading and extracting ${luks_tests} into ${luks_tests_folder} did not complete successfully" 232 exit 1 233 fi 234 fi 235 236 return 0 237 fi 238 239 # create list of password and hashes of same type 240 cmd_file=${OUTD}/${hash_type}.sh 241 242 grep " ${hash_type} '" "${OUTD}/all.sh" > "${cmd_file}" 2>/dev/null 243 244 # create separate list of password and hashes 245 sed 's/^echo *|.*$//' "${cmd_file}" | awk '{print $2}' > "${OUTD}/${hash_type}_passwords.txt" 246 sed 's/^echo *|/echo "" |/' "${cmd_file}" | awk '{print $10}' | cut -d"'" -f2 > "${OUTD}/${hash_type}_hashes.txt" 247 248 if [ "${hash_type}" -eq 10300 ]; then 249 #cat ${OUTD}/${hash_type}.sh | cut -d' ' -f11- | cut -d"'" -f2 > ${OUTD}/${hash_type}_hashes.txt 250 cut -d"'" -f2 "${OUTD}/${hash_type}.sh" > "${OUTD}/${hash_type}_hashes.txt" 251 fi 252 253 # truncate dicts 254 rm -rf "${OUTD}/${hash_type}_dict1" "${OUTD}/${hash_type}_dict2" 255 touch "${OUTD}/${hash_type}_dict1" "${OUTD}/${hash_type}_dict2" 256 257 # minimum password length 258 259 min=1 # minimum line number from start of the file 260 min_offset=0 # minimum offset starting from ${min} lines 261 262 if [ "${hash_type}" -eq 2500 ]; then 263 min_offset=7 # means length 8, since we start with 0 264 elif [ "${hash_type}" -eq 14000 ]; then 265 min=0 266 min_offset=4 267 elif [ "${hash_type}" -eq 14100 ]; then 268 min=0 269 min_offset=3 270 elif [ "${hash_type}" -eq 14900 ]; then 271 min=0 272 min_offset=5 273 elif [ "${hash_type}" -eq 15400 ]; then 274 min=0 275 min_offset=3 276 elif [ "${hash_type}" -eq 16800 ]; then 277 min_offset=7 # means length 8, since we start with 0 278 elif [ "${hash_type}" -eq 22000 ]; then 279 min_offset=7 # means length 8, since we start with 0 280 fi 281 282 # foreach password entry split password in 2 (skip first entry, is len 1) 283 284 i=1 285 286 while read -r -u 9 pass; do 287 288 if [ ${i} -gt ${min} ]; then 289 290 # split password, 'i' is the len 291 p0=$((i / 2)) 292 p1=$((p0 + 1)) 293 294 # special case (passwords longer than expected) 295 pass_len=${#pass} 296 297 if [ "${pass_len}" -gt 1 ] 298 then 299 300 p1=$((p1 + min_offset)) 301 p0=$((p0 + min_offset)) 302 303 if [ "${p1}" -gt "${pass_len}" ]; then 304 305 p1=${pass_len} 306 p0=$((p1 - 1)) 307 308 fi 309 310 # add splitted password to dicts 311 echo "${pass}" | cut -c -${p0} >> "${OUTD}/${hash_type}_dict1" 312 echo "${pass}" | cut -c ${p1}- >> "${OUTD}/${hash_type}_dict2" 313 elif [ "${pass_len}" -eq 1 ]; then 314 echo "${pass}" >> "${OUTD}/${hash_type}_dict1" 315 echo >> "${OUTD}/${hash_type}_dict2" 316 else 317 echo >> "${OUTD}/${hash_type}_dict1" 318 echo >> "${OUTD}/${hash_type}_dict2" 319 fi 320 321 fi 322 323 i=$((i + 1)) 324 325 done 9< "${OUTD}/${hash_type}_passwords.txt" 326 327 min_len=0 328 329 if [ "${hash_type}" -eq 2500 ]; then 330 min_len=7 # means length 8, since we start with 0 331 elif [ "${hash_type}" -eq 14000 ]; then 332 min_len=7 333 elif [ "${hash_type}" -eq 14100 ]; then 334 min_len=23 335 elif [ "${hash_type}" -eq 14900 ]; then 336 min_len=9 337 elif [ "${hash_type}" -eq 15400 ]; then 338 min_len=31 339 elif [ "${hash_type}" -eq 16800 ]; then 340 min_len=7 # means length 8, since we start with 0 341 elif [ "${hash_type}" -eq 22000 ]; then 342 min_len=7 # means length 8, since we start with 0 343 fi 344 345 # generate multiple pass/hash foreach len (2 to 8) 346 if [ "${MODE}" -ge 1 ]; then 347 348 i=2 349 while [ "$i" -lt 9 ]; do 350 351 cmd_file=${OUTD}/${hash_type}_multi_${i}.txt 352 353 rm -rf "${cmd_file}" "${OUTD}/${hash_type}_passwords_multi_${i}.txt" "${OUTD}/${hash_type}_hashes_multi_${i}.txt" 354 rm -rf "${OUTD}/${hash_type}_dict1_multi_${i}" "${OUTD}/${hash_type}_dict2_multi_${i}" 355 touch "${OUTD}/${hash_type}_dict1_multi_${i}" "${OUTD}/${hash_type}_dict2_multi_${i}" 356 357 perl tools/test.pl single "${hash_type}" ${i} > "${cmd_file}" 358 359 sed 's/^echo *|.*$//' "${cmd_file}" | awk '{print $2}' > "${OUTD}/${hash_type}_passwords_multi_${i}.txt" 360 sed 's/^echo *|/echo "" |/' "${cmd_file}" | awk '{print $10}' | cut -d"'" -f2 > "${OUTD}/${hash_type}_hashes_multi_${i}.txt" 361 362 if [ "${hash_type}" -eq 10300 ]; then 363 #cat ${OUTD}/${hash_type}_multi_${i}.txt | cut -d' ' -f11- | cut -d"'" -f2 > ${OUTD}/${hash_type}_hashes_multi_${i}.txt 364 cut -d"'" -f2 "${OUTD}/${hash_type}_multi_${i}.txt" > "${OUTD}/${hash_type}_hashes_multi_${i}.txt" 365 fi 366 367 # split password, 'i' is the len 368 p0=$((i / 2)) 369 p1=$((p0 + 1)) 370 371 p0=$((p0 + min_len)) 372 p1=$((p1 + min_len)) 373 374 while read -r -u 9 pass; do 375 376 # add splitted password to dicts 377 echo "${pass}" | cut -c -${p0} >> "${OUTD}/${hash_type}_dict1_multi_${i}" 378 echo "${pass}" | cut -c ${p1}- >> "${OUTD}/${hash_type}_dict2_multi_${i}" 379 380 done 9< "${OUTD}/${hash_type}_passwords_multi_${i}.txt" 381 i=$((i + 1)) 382 383 done 384 385 fi 386} 387 388function status() 389{ 390 RET=$1 391 392 cnt=$((cnt + 1)) 393 394 if [ "${RET}" -ne 0 ]; then 395 case ${RET} in 396 1) 397 if ! is_in_array "${hash_type}" ${NEVER_CRACK_ALGOS}; then 398 399 echo "password not found, cmdline : ${CMD}" >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 400 e_nf=$((e_nf + 1)) 401 402 fi 403 404 ;; 405 4) 406 echo "timeout reached, cmdline : ${CMD}" >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 407 e_to=$((e_to + 1)) 408 409 ;; 410 10) 411 if is_in_array "${hash_type}" ${NEVER_CRACK_ALGOS}; then 412 return 413 fi 414 415 if [ "${pass_only}" -eq 1 ]; then 416 echo "plains not found in output, cmdline : ${CMD}" >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 417 else 418 echo "hash:plains not matched in output, cmdline : ${CMD}" >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.tx"t 419 fi 420 e_nm=$((e_nm + 1)) 421 422 ;; 423 *) 424 echo "! unhandled return code ${RET}, cmdline : ${CMD}" >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 425 echo "! unhandled return code, see ${OUTD}/logfull.txt for details." 426 e_nf=$((e_nf + 1)) 427 ;; 428 esac 429 fi 430} 431 432function attack_0() 433{ 434 file_only=0 435 436 if is_in_array "${hash_type}" ${FILE_BASED_ALGOS}; then 437 438 file_only=1 439 440 fi 441 442 # single hash 443 if [ "${MODE}" -ne 1 ]; then 444 445 e_to=0 446 e_nf=0 447 e_nm=0 448 cnt=0 449 450 echo "> Testing hash type $hash_type with attack mode 0, markov ${MARKOV}, single hash, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}." >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 451 452 max=32 453 454 if is_in_array "${hash_type}" ${TIMEOUT_ALGOS}; then 455 456 max=12 457 458 fi 459 460 i=0 461 462 while read -r -u 9 line; do 463 464 if [ "${i}" -ge ${max} ]; then 465 466 break 467 468 fi 469 470 hash="$(echo "${line}" | cut -d\' -f2)" 471 pass="$(echo "${line}" | cut -d' ' -f2)" 472 473 if [ -z "${hash}" ]; then 474 475 break 476 477 fi 478 479 if [ "${file_only}" -eq 1 ]; then 480 481 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt" 482 483 if [ "${hash_type}" -ne 22000 ]; then 484 echo "${hash}" | base64 -d > "${temp_file}" 485 else 486 echo "${hash}" > "${temp_file}" 487 fi 488 489 hash="${temp_file}" 490 491 fi 492 493 pass_old=${pass} 494 495 if [ "${hash_type}" -eq 20510 ]; then # special case for PKZIP Master Key 496 pass=$(echo "${pass}" | cut -b 7-) # skip the first 6 chars 497 fi 498 499 CMD="echo ${pass} | ./${BIN} ${OPTS} -a 0 -m ${hash_type} '${hash}'" 500 501 echo -n "[ len $((i + 1)) ] " >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 502 503 output=$(echo "${pass}" | ./${BIN} ${OPTS} -a 0 -m ${hash_type} "${hash}" 2>&1) 504 505 ret=${?} 506 507 pass=${pass_old} 508 509 echo "${output}" >> "${OUTD}/logfull.txt" 510 511 if [ "${ret}" -eq 0 ]; then 512 513 if [ "${pass_only}" -eq 1 ]; then 514 search=":${pass}" 515 else 516 search="${hash}:${pass}" 517 fi 518 519 echo "${output}" | grep -F "${search}" >/dev/null 2>/dev/null 520 521 if [ "${?}" -ne 0 ]; then 522 523 ret=10 524 525 fi 526 527 fi 528 529 status ${ret} 530 531 i=$((i + 1)) 532 533 done 9< "${OUTD}/${hash_type}.sh" 534 535 msg="OK" 536 537 if [ "${e_nf}" -ne 0 ] || [ "${e_nm}" -ne 0 ]; then 538 539 msg="Error" 540 541 elif [ "${e_to}" -ne 0 ]; then 542 543 msg="Warning" 544 545 fi 546 547 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 0, Mode single, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout" 548 549 fi 550 551 # multihash 552 if [ "${MODE}" -ne 0 ]; then 553 554 e_to=0 555 e_nf=0 556 e_nm=0 557 cnt=0 558 559 echo "> Testing hash type $hash_type with attack mode 0, markov ${MARKOV}, multi hash, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}." >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 560 561 hash_file=${OUTD}/${hash_type}_hashes.txt 562 563 # if file_only -> decode all base64 "hashes" and put them in the temporary file 564 565 if [ "${file_only}" -eq 1 ]; then 566 567 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt" 568 rm -f "${temp_file}" 569 570 hash_file=${temp_file} 571 572 while read -r file_only_hash; do 573 574 if [ "${hash_type}" -ne 22000 ]; then 575 echo -n "${file_only_hash}" | base64 -d >> "${temp_file}" 576 else 577 echo "${file_only_hash}" >> "${temp_file}" 578 fi 579 580 done < "${OUTD}/${hash_type}_hashes.txt" 581 582 fi 583 584 CMD="cat ${OUTD}/${hash_type}_passwords.txt | ./${BIN} ${OPTS} -a 0 -m ${hash_type} ${hash_file}" 585 586 output=$(./${BIN} ${OPTS} -a 0 -m ${hash_type} ${hash_file} < ${OUTD}/${hash_type}_passwords.txt 2>&1) 587 588 ret=${?} 589 590 echo "${output}" >> "${OUTD}/logfull.txt" 591 592 if [ "${ret}" -eq 0 ]; then 593 594 i=1 595 596 while read -r -u 9 hash; do 597 598 pass=$(sed -n ${i}p "${OUTD}/${hash_type}_passwords.txt") 599 600 if [ "${pass_only}" -eq 1 ]; then 601 search=":${pass}" 602 else 603 search="${hash}:${pass}" 604 fi 605 606 echo "${output}" | grep -F "${search}" >/dev/null 2>/dev/null 607 608 if [ "${?}" -ne 0 ]; then 609 610 ret=10 611 612 break 613 614 fi 615 616 i=$((i + 1)) 617 618 done 9< "${OUTD}/${hash_type}_hashes.txt" 619 620 fi 621 622 status ${ret} 623 624 msg="OK" 625 626 if [ "${e_nf}" -ne 0 ] || [ "${e_nm}" -ne 0 ]; then 627 628 msg="Error" 629 630 elif [ "${e_to}" -ne 0 ]; then 631 632 msg="Warning" 633 634 fi 635 636 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 0, Mode multi, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout" 637 638 fi 639} 640 641function attack_1() 642{ 643 file_only=0 644 645 if is_in_array "${hash_type}" ${FILE_BASED_ALGOS}; then 646 647 file_only=1 648 649 fi 650 651 # single hash 652 if [ "${MODE}" -ne 1 ]; then 653 654 e_to=0 655 e_nf=0 656 e_nm=0 657 cnt=0 658 659 min=1 660 max=8 661 662 if [ "${hash_type}" -eq 14000 ]; then 663 min=0 664 max=5 665 elif [ "${hash_type}" -eq 14100 ]; then 666 min=0 667 max=5 668 elif [ "${hash_type}" -eq 14900 ]; then 669 min=0 670 max=5 671 elif [ "${hash_type}" -eq 15400 ]; then 672 min=0 673 max=5 674 fi 675 676 echo "> Testing hash type $hash_type with attack mode 1, markov ${MARKOV}, single hash, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}." >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 677 i=1 678 while read -r -u 9 hash; do 679 680 if [ $i -gt ${min} ]; then 681 682 if [ "${file_only}" -eq 1 ]; then 683 684 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt" 685 686 if [ "${hash_type}" -ne 22000 ]; then 687 echo "${hash}" | base64 -d > "${temp_file}" 688 else 689 echo "${hash}" > "${temp_file}" 690 fi 691 692 hash="${temp_file}" 693 694 fi 695 696 line_nr=1 697 698 if [ "$min" -eq 0 ]; then 699 line_nr=$i 700 elif [ "${i}" -gt 1 ]; then 701 line_nr=$((i - 1)) 702 fi 703 704 dict1="${OUTD}/${hash_type}_dict1" 705 dict2="${OUTD}/${hash_type}_dict2" 706 707 if [ "${hash_type}" -eq 20510 ]; then # special case for PKZIP Master Key 708 line_dict1=$(sed -n ${line_nr}p "${dict1}") 709 line_dict2=$(sed -n ${line_nr}p "${dict2}") 710 line_num=$(wc -l "${dict1}" | sed -E 's/ *([0-9]+) .*$/\1/') 711 712 line_dict1_orig=${line_dict1} 713 line_dict2_orig=${line_dict2} 714 715 if [ "${#line_dict1}" -ge 6 ]; then 716 line_dict1=$(echo "${line_dict1}" | cut -b 7-) # skip the first 6 chars 717 else 718 # we need to also "steal" some chars from the second dict 719 num_to_steal=$((6 - ${#line_dict1})) 720 num_steal_start=$((num_to_steal + 1)) 721 722 if [ "${#line_dict2}" -ge 6 ]; then 723 num_to_steal_new=$(((${#line_dict2} - num_to_steal) / 2)) 724 725 if [ "${num_to_steal_new}" -gt ${num_to_steal} ]; then 726 num_to_steal=${num_to_steal_new} 727 fi 728 fi 729 730 line_chars_stolen=$(echo "${line_dict2}" | cut -b -${num_to_steal} | cut -b ${num_steal_start}-) 731 732 line_dict1="${line_chars_stolen}" 733 line_dict2=$(echo "${line_dict2}" | cut -b $((num_to_steal + 1))-) 734 fi 735 736 # finally, modify the dicts accordingly: 737 738 tmp_file="${dict1}_mod" 739 740 head -n $((line_nr - 1)) "${dict1}" > "${tmp_file}" 741 echo "${line_dict1}" >> "${tmp_file}" 742 tail -n $((line_num - line_nr - 1)) "${dict1}" >> "${tmp_file}" 743 744 dict1=${tmp_file} 745 746 tmp_file="${dict2}_mod" 747 748 head -n $((line_nr - 1)) "${dict2}" > "${tmp_file}" 749 echo "${line_dict2}" >> "${tmp_file}" 750 tail -n $((line_num - line_nr - 1)) "${dict2}" >> "${tmp_file}" 751 752 dict2=${tmp_file} 753 fi 754 755 CMD="./${BIN} ${OPTS} -a 1 -m ${hash_type} '${hash}' ${dict1} ${dict2}" 756 757 echo -n "[ len $i ] " >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 758 759 output=$(./${BIN} ${OPTS} -a 1 -m ${hash_type} "${hash}" ${dict1} ${dict2} 2>&1) 760 761 ret=${?} 762 763 echo "${output}" >> "${OUTD}/logfull.txt" 764 765 if [ "${ret}" -eq 0 ]; then 766 767 line_dict1=$(sed -n ${line_nr}p "${OUTD}/${hash_type}_dict1") 768 line_dict2=$(sed -n ${line_nr}p "${OUTD}/${hash_type}_dict2") 769 770 if [ "${pass_only}" -eq 1 ]; then 771 search=":${line_dict1}${line_dict2}" 772 else 773 search="${hash}:${line_dict1}${line_dict2}" 774 fi 775 776 echo "${output}" | grep -F "${search}" >/dev/null 2>/dev/null 777 778 if [ "${?}" -ne 0 ]; then 779 780 ret=10 781 782 fi 783 784 fi 785 786 status ${ret} 787 788 fi 789 790 if [ $i -eq ${max} ]; then break; fi 791 792 i=$((i + 1)) 793 794 done 9< "${OUTD}/${hash_type}_hashes.txt" 795 796 msg="OK" 797 798 if [ "${e_nf}" -ne 0 ] || [ "${e_nm}" -ne 0 ]; then 799 800 msg="Error" 801 802 elif [ "${e_to}" -ne 0 ]; then 803 804 msg="Warning" 805 806 fi 807 808 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 1, Mode single, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout" 809 810 fi 811 812 # multihash 813 if [ "${MODE}" -ne 0 ]; then 814 815 # no multi hash checks for these modes (because we only have 1 hash for each of them) 816 817 if [ "${hash_type}" -eq 14000 ]; then 818 return 819 elif [ "${hash_type}" -eq 14100 ]; then 820 return 821 elif [ "${hash_type}" -eq 14900 ]; then 822 return 823 elif [ "${hash_type}" -eq 15400 ]; then 824 return 825 fi 826 827 e_to=0 828 e_nf=0 829 e_nm=0 830 cnt=0 831 832 offset=7 833 834 if [ "${hash_type}" -eq 5800 ]; then 835 offset=6 836 elif [ "${hash_type}" -eq 3000 ]; then 837 offset=6 838 fi 839 840 hash_file=${OUTD}/${hash_type}_multihash_combi.txt 841 842 tail -n ${offset} "${OUTD}/${hash_type}_hashes.txt" > "${hash_file}" 843 844 # if file_only -> decode all base64 "hashes" and put them in the temporary file 845 846 if [ "${file_only}" -eq 1 ]; then 847 848 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt" 849 rm -f "${temp_file}" 850 851 hash_file=${temp_file} 852 853 while read -r file_only_hash; do 854 855 if [ "${hash_type}" -ne 22000 ]; then 856 echo -n "${file_only_hash}" | base64 -d >> "${temp_file}" 857 else 858 echo "${file_only_hash}" >> "${temp_file}" 859 fi 860 861 done < "${OUTD}/${hash_type}_multihash_combi.txt" 862 863 fi 864 865 CMD="./${BIN} ${OPTS} -a 1 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2" 866 867 echo "> Testing hash type $hash_type with attack mode 1, markov ${MARKOV}, multi hash, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}." >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 868 869 output=$(./${BIN} ${OPTS} -a 1 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1 ${OUTD}/${hash_type}_dict2 2>&1) 870 871 ret=${?} 872 873 echo "${output}" >> "${OUTD}/logfull.txt" 874 875 if [ "${ret}" -eq 0 ]; then 876 877 i=0 878 879 while read -r -u 9 hash; do 880 881 line_nr=1 882 883 if [ "${offset}" -gt ${i} ]; then 884 line_nr=$((offset - i)) 885 fi 886 887 line_dict1=$(tail -n ${line_nr} "${OUTD}/${hash_type}_dict1" | head -1) 888 line_dict2=$(tail -n ${line_nr} "${OUTD}/${hash_type}_dict2" | head -1) 889 890 if [ "${pass_only}" -eq 1 ]; then 891 search=":${line_dict1}${line_dict2}" 892 else 893 search="${hash}:${line_dict1}${line_dict2}" 894 fi 895 896 echo "${output}" | grep -F "${search}" >/dev/null 2>/dev/null 897 898 if [ "${?}" -ne 0 ]; then 899 900 ret=10 901 902 break 903 904 fi 905 906 i=$((i + 1)) 907 908 done 9< "${OUTD}/${hash_type}_multihash_combi.txt" 909 910 fi 911 912 status ${ret} 913 914 msg="OK" 915 916 if [ "${e_nf}" -ne 0 ] || [ "${e_nm}" -ne 0 ]; then 917 918 msg="Error" 919 920 elif [ "${e_to}" -ne 0 ]; then 921 922 msg="Warning" 923 924 fi 925 926 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 1, Mode multi, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout" 927 928 fi 929} 930 931function attack_3() 932{ 933 file_only=0 934 935 if is_in_array "${hash_type}" ${FILE_BASED_ALGOS}; then 936 937 file_only=1 938 939 fi 940 941 # single hash 942 if [ "${MODE}" -ne 1 ]; then 943 944 e_to=0 945 e_nf=0 946 e_nm=0 947 cnt=0 948 949 echo "> Testing hash type $hash_type with attack mode 3, markov ${MARKOV}, single hash, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}." >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 950 951 max=8 952 953 # some algos have a minimum password length 954 955 if [ "${hash_type}" -eq 2500 ]; then 956 max=7 957 elif [ "${hash_type}" -eq 14000 ]; then 958 max=1 959 elif [ "${hash_type}" -eq 14100 ]; then 960 max=1 961 elif [ "${hash_type}" -eq 14900 ]; then 962 max=1 963 elif [ "${hash_type}" -eq 15400 ]; then 964 max=1 965 elif [ "${hash_type}" -eq 16800 ]; then 966 max=7 967 elif [ "${hash_type}" -eq 22000 ]; then 968 max=7 969 fi 970 971 i=1 972 973 while read -r -u 9 hash; do 974 975 if [ "${i}" -gt 6 ]; then 976 977 if is_in_array "${hash_type}" ${TIMEOUT_ALGOS}; then 978 979 break 980 981 fi 982 983 fi 984 985 if [ "${file_only}" -eq 1 ]; then 986 987 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt" 988 989 if [ "${hash_type}" -ne 22000 ]; then 990 echo "${hash}" | base64 -d > "${temp_file}" 991 else 992 echo "${hash}" > "${temp_file}" 993 fi 994 995 hash="${temp_file}" 996 997 fi 998 999 1000 # construct a meaningful mask from the password itself: 1001 1002 dict="${OUTD}/${hash_type}_passwords.txt" 1003 1004 pass=$(sed -n ${i}p "${dict}") 1005 1006 # passwords can't be smaller than mask in -a 3 = mask attack 1007 1008 if [ "${#pass}" -lt ${i} ]; then 1009 i=$((i + 1)) 1010 continue 1011 fi 1012 1013 pass_part_2=$(echo -n "${pass}" | cut -b $((i + 1))-) 1014 1015 mask="" 1016 1017 if [ "${hash_type}" -eq 14000 ]; then 1018 1019 mask="${pass}" 1020 1021 elif [ "${hash_type}" -eq 14100 ]; then 1022 1023 mask="${pass}" 1024 1025 else 1026 1027 for i in $(seq 1 ${i}); do 1028 mask="${mask}?d" 1029 done 1030 1031 mask="${mask}${pass_part_2}" 1032 1033 fi 1034 1035 if [ "${hash_type}" -eq 20510 ]; then # special case for PKZIP Master Key 1036 if [ "${i}" -le 1 ]; then 1037 i=$((i + 1)) 1038 continue 1039 fi 1040 1041 cut_pos=$((i * 2 + 6 - i + 1)) # skip it in groups of 2 ("?d"), at least 6, offset +1 for cut to work 1042 1043 if [ "${i}" -gt 6 ]; then 1044 cut_pos=13 # 6 * ?d + 1 (6 * 2 + 1) 1045 fi 1046 1047 mask=$(echo "${mask}" | cut -b ${cut_pos}-) 1048 fi 1049 1050 CMD="./${BIN} ${OPTS} -a 3 -m ${hash_type} '${hash}' ${mask}" 1051 1052 echo -n "[ len $i ] " >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 1053 1054 output=$(./${BIN} ${OPTS} -a 3 -m ${hash_type} "${hash}" ${mask} 2>&1) 1055 1056 ret=${?} 1057 1058 echo "${output}" >> "${OUTD}/logfull.txt" 1059 1060 if [ "${ret}" -eq 0 ]; then 1061 1062 line_dict=$(sed -n ${i}p "${dict}") 1063 1064 if [ "${pass_only}" -eq 1 ]; then 1065 search=":${line_dict}" 1066 else 1067 search="${hash}:${line_dict}" 1068 fi 1069 1070 echo "${output}" | grep -F "${search}" >/dev/null 2>/dev/null 1071 1072 if [ "${?}" -ne 0 ]; then 1073 1074 ret=10 1075 1076 fi 1077 1078 fi 1079 1080 status ${ret} 1081 1082 if [ $i -eq ${max} ]; then break; fi 1083 1084 i=$((i + 1)) 1085 1086 done 9< "${OUTD}/${hash_type}_hashes.txt" 1087 1088 msg="OK" 1089 1090 if [ "${e_nf}" -ne 0 ] || [ "${e_nm}" -ne 0 ]; then 1091 1092 msg="Error" 1093 1094 elif [ "${e_to}" -ne 0 ]; then 1095 1096 msg="Warning" 1097 1098 fi 1099 1100 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 3, Mode single, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout" 1101 1102 fi 1103 1104 # multihash 1105 if [ "${MODE}" -ne 0 ]; then 1106 1107 # no multi hash checks for these modes (because we only have 1 hash for each of them) 1108 1109 if [ "${hash_type}" -eq 14000 ]; then 1110 return 1111 elif [ "${hash_type}" -eq 14100 ]; then 1112 return 1113 elif [ "${hash_type}" -eq 14900 ]; then 1114 return 1115 elif [ "${hash_type}" -eq 15400 ]; then 1116 return 1117 fi 1118 1119 e_to=0 1120 e_nf=0 1121 e_nm=0 1122 cnt=0 1123 1124 increment_max=8 1125 1126 if is_in_array "${hash_type}" ${TIMEOUT_ALGOS}; then 1127 1128 increment_max=5 1129 1130 fi 1131 1132 increment_min=1 1133 1134 if [ "${hash_type}" -eq 2500 ]; then 1135 increment_min=8 1136 increment_max=9 1137 fi 1138 1139 if [ "${hash_type}" -eq 16800 ]; then 1140 increment_min=8 1141 increment_max=9 1142 fi 1143 1144 if [ "${hash_type}" -eq 22000 ]; then 1145 increment_min=8 1146 increment_max=9 1147 fi 1148 1149 # if file_only -> decode all base64 "hashes" and put them in the temporary file 1150 1151 if [ "${file_only}" -eq 1 ]; then 1152 1153 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt" 1154 rm -f "${temp_file}" 1155 1156 hash_file=${temp_file} 1157 1158 while read -r file_only_hash; do 1159 1160 if [ "${hash_type}" -ne 22000 ]; then 1161 echo -n "${file_only_hash}" | base64 -d >> "${temp_file}" 1162 else 1163 echo "${file_only_hash}" >> "${temp_file}" 1164 fi 1165 1166 done < "${OUTD}/${hash_type}_multihash_bruteforce.txt" 1167 1168 fi 1169 1170 hash_file=${OUTD}/${hash_type}_multihash_bruteforce.txt 1171 1172 tail_hashes=$(awk "length >= ${increment_min} && length <= ${increment_max}" "${OUTD}/${hash_type}_passwords.txt" | wc -l) 1173 head_hashes=$(awk "length <= ${increment_max}" "${OUTD}/${hash_type}_passwords.txt" | wc -l) 1174 1175 # in very rare cases (e.g. without -O and long passwords) we need to use .hcmask files with the passwords in it 1176 # otherwise there are no good masks we can test for such long passwords 1177 1178 need_hcmask=0 1179 1180 if [ "${tail_hashes}" -gt "${head_hashes}" ]; then 1181 need_hcmask=1 1182 fi 1183 1184 if [ "${tail_hashes}" -lt 1 ]; then 1185 need_hcmask=1 1186 fi 1187 1188 if [ ${need_hcmask} -eq 0 ]; then 1189 head -n "${head_hashes}" "${OUTD}/${hash_type}_hashes.txt" | tail -n "${tail_hashes}" > "${hash_file}" 1190 else 1191 tail_hashes=$(awk "length >= ${increment_min}" "${OUTD}/${hash_type}_passwords.txt" | wc -l) 1192 1193 if [ "${tail_hashes}" -lt 1 ]; then 1194 return 1195 fi 1196 1197 tail -n "${tail_hashes}" "${OUTD}/${hash_type}_hashes.txt" > "${hash_file}" 1198 fi 1199 1200 mask_pos=8 1201 1202 if [ "${increment_min}" -gt ${mask_pos} ]; then 1203 mask_pos=${increment_min} 1204 fi 1205 1206 mask="" 1207 cracks_offset=0 1208 1209 if [ ${need_hcmask} -eq 0 ]; then 1210 cracks_offset=$((head_hashes - tail_hashes)) 1211 1212 mask=${mask_3[${mask_pos}]} 1213 else 1214 num_hashes=$(wc -l < "${OUTD}/${hash_type}_hashes.txt") 1215 cracks_offset=$((num_hashes - tail_hashes)) 1216 1217 mask=${OUTD}/${hash_type}_passwords.txt # fake hcmask file (i.e. the original dict) 1218 fi 1219 1220 custom_charsets="" 1221 1222 # modify "default" mask if needed (and set custom charset to reduce keyspace) 1223 1224 if [ "${hash_type}" -eq 2500 ]; then 1225 1226 mask="?d?d?d?d?d?1?2?3?4" 1227 1228 charset_1="" 1229 charset_2="" 1230 charset_3="" 1231 charset_4="" 1232 1233 # check positions (here we assume that mask is always composed of non literal chars 1234 # i.e. something like ?d?l?u?s?1 is possible, but ?d?dsuffix not 1235 charset_1_pos=$(expr index "${mask}" 1) 1236 charset_2_pos=$(expr index "${mask}" 2) 1237 charset_3_pos=$(expr index "${mask}" 3) 1238 charset_4_pos=$(expr index "${mask}" 4) 1239 1240 # divide each charset position by 2 since each of them occupies 2 positions in the mask 1241 1242 charset_1_pos=$((charset_1_pos / 2)) 1243 charset_2_pos=$((charset_2_pos / 2)) 1244 charset_3_pos=$((charset_3_pos / 2)) 1245 charset_4_pos=$((charset_4_pos / 2)) 1246 1247 i=1 1248 1249 while read -r -u 9 hash; do 1250 1251 pass=$(sed -n ${i}p "${OUTD}/${hash_type}_passwords.txt") 1252 1253 # charset 1 1254 char=$(echo "${pass}" | cut -b ${charset_1_pos}) 1255 charset_1=$(printf "%s\n%s\n" "${charset_1}" "${char}") 1256 1257 # charset 2 1258 char=$(echo "${pass}" | cut -b ${charset_2_pos}) 1259 charset_2=$(printf "%s\n%s\n" "${charset_2}" "${char}") 1260 1261 # charset 3 1262 char=$(echo "${pass}" | cut -b ${charset_3_pos}) 1263 charset_3=$(printf "%s\n%s\n" "${charset_3}" "${char}") 1264 1265 # charset 4 1266 char=$(echo "${pass}" | cut -b ${charset_4_pos}) 1267 charset_4=$(printf "%s\n%s\n" "${charset_4}" "${char}") 1268 1269 i=$((i + 1)) 1270 1271 done 9< "${OUTD}/${hash_type}_multihash_bruteforce.txt" 1272 1273 # just make sure that all custom charset fields are initialized 1274 1275 if [ -z "${charset_1}" ]; then 1276 1277 charset_1="1" 1278 1279 fi 1280 1281 if [ -z "${charset_2}" ]; then 1282 1283 charset_2="2" 1284 1285 fi 1286 1287 if [ -z "${charset_3}" ]; then 1288 1289 charset_3="3" 1290 1291 fi 1292 1293 if [ -z "${charset_4}" ]; then 1294 1295 charset_4="4" 1296 1297 fi 1298 1299 # unique and remove new lines 1300 1301 charset_1=$(echo "${charset_1}" | sort -u | tr -d '\n') 1302 charset_2=$(echo "${charset_2}" | sort -u | tr -d '\n') 1303 charset_3=$(echo "${charset_3}" | sort -u | tr -d '\n') 1304 charset_4=$(echo "${charset_4}" | sort -u | tr -d '\n') 1305 1306 custom_charsets="-1 ${charset_1} -2 ${charset_2} -3 ${charset_3} -4 ${charset_4}" 1307 fi 1308 1309 if [ "${hash_type}" -eq 16800 ]; then 1310 1311 mask="?d?d?d?d?d?1?2?3?4" 1312 1313 charset_1="" 1314 charset_2="" 1315 charset_3="" 1316 charset_4="" 1317 1318 # check positions (here we assume that mask is always composed of non literal chars 1319 # i.e. something like ?d?l?u?s?1 is possible, but ?d?dsuffix not 1320 charset_1_pos=$(expr index "${mask}" 1) 1321 charset_2_pos=$(expr index "${mask}" 2) 1322 charset_3_pos=$(expr index "${mask}" 3) 1323 charset_4_pos=$(expr index "${mask}" 4) 1324 1325 # divide each charset position by 2 since each of them occupies 2 positions in the mask 1326 1327 charset_1_pos=$((charset_1_pos / 2)) 1328 charset_2_pos=$((charset_2_pos / 2)) 1329 charset_3_pos=$((charset_3_pos / 2)) 1330 charset_4_pos=$((charset_4_pos / 2)) 1331 1332 i=1 1333 1334 while read -r -u 9 hash; do 1335 1336 pass=$(sed -n ${i}p "${OUTD}/${hash_type}_passwords.txt") 1337 1338 # charset 1 1339 char=$(echo "${pass}" | cut -b ${charset_1_pos}) 1340 charset_1=$(printf "%s\n%s\n" "${charset_1}" "${char}") 1341 1342 # charset 2 1343 char=$(echo "${pass}" | cut -b ${charset_2_pos}) 1344 charset_2=$(printf "%s\n%s\n" "${charset_2}" "${char}") 1345 1346 # charset 3 1347 char=$(echo "${pass}" | cut -b ${charset_3_pos}) 1348 charset_3=$(printf "%s\n%s\n" "${charset_3}" "${char}") 1349 1350 # charset 4 1351 char=$(echo "${pass}" | cut -b ${charset_4_pos}) 1352 charset_4=$(printf "%s\n%s\n" "${charset_4}" "${char}") 1353 1354 i=$((i + 1)) 1355 1356 done 9< "${OUTD}/${hash_type}_multihash_bruteforce.txt" 1357 1358 # just make sure that all custom charset fields are initialized 1359 1360 if [ -z "${charset_1}" ]; then 1361 1362 charset_1="1" 1363 1364 fi 1365 1366 if [ -z "${charset_2}" ]; then 1367 1368 charset_2="2" 1369 1370 fi 1371 1372 if [ -z "${charset_3}" ]; then 1373 1374 charset_3="3" 1375 1376 fi 1377 1378 if [ -z "${charset_4}" ]; then 1379 1380 charset_4="4" 1381 1382 fi 1383 1384 # unique and remove new lines 1385 1386 charset_1=$(echo "${charset_1}" | sort -u | tr -d '\n') 1387 charset_2=$(echo "${charset_2}" | sort -u | tr -d '\n') 1388 charset_3=$(echo "${charset_3}" | sort -u | tr -d '\n') 1389 charset_4=$(echo "${charset_4}" | sort -u | tr -d '\n') 1390 1391 custom_charsets="-1 ${charset_1} -2 ${charset_2} -3 ${charset_3} -4 ${charset_4}" 1392 fi 1393 1394 if [ "${hash_type}" -eq 22000 ]; then 1395 1396 mask="?d?d?d?d?d?1?2?3?4" 1397 1398 charset_1="" 1399 charset_2="" 1400 charset_3="" 1401 charset_4="" 1402 1403 # check positions (here we assume that mask is always composed of non literal chars 1404 # i.e. something like ?d?l?u?s?1 is possible, but ?d?dsuffix not 1405 charset_1_pos=$(expr index "${mask}" 1) 1406 charset_2_pos=$(expr index "${mask}" 2) 1407 charset_3_pos=$(expr index "${mask}" 3) 1408 charset_4_pos=$(expr index "${mask}" 4) 1409 1410 # divide each charset position by 2 since each of them occupies 2 positions in the mask 1411 1412 charset_1_pos=$((charset_1_pos / 2)) 1413 charset_2_pos=$((charset_2_pos / 2)) 1414 charset_3_pos=$((charset_3_pos / 2)) 1415 charset_4_pos=$((charset_4_pos / 2)) 1416 1417 i=1 1418 1419 while read -r -u 9 hash; do 1420 1421 pass=$(sed -n ${i}p "${OUTD}/${hash_type}_passwords.txt") 1422 1423 # charset 1 1424 char=$(echo "${pass}" | cut -b ${charset_1_pos}) 1425 charset_1=$(printf "%s\n%s\n" "${charset_1}" "${char}") 1426 1427 # charset 2 1428 char=$(echo "${pass}" | cut -b ${charset_2_pos}) 1429 charset_2=$(printf "%s\n%s\n" "${charset_2}" "${char}") 1430 1431 # charset 3 1432 char=$(echo "${pass}" | cut -b ${charset_3_pos}) 1433 charset_3=$(printf "%s\n%s\n" "${charset_3}" "${char}") 1434 1435 # charset 4 1436 char=$(echo "${pass}" | cut -b ${charset_4_pos}) 1437 charset_4=$(printf "%s\n%s\n" "${charset_4}" "${char}") 1438 1439 i=$((i + 1)) 1440 1441 done 9< "${OUTD}/${hash_type}_multihash_bruteforce.txt" 1442 1443 # just make sure that all custom charset fields are initialized 1444 1445 if [ -z "${charset_1}" ]; then 1446 1447 charset_1="1" 1448 1449 fi 1450 1451 if [ -z "${charset_2}" ]; then 1452 1453 charset_2="2" 1454 1455 fi 1456 1457 if [ -z "${charset_3}" ]; then 1458 1459 charset_3="3" 1460 1461 fi 1462 1463 if [ -z "${charset_4}" ]; then 1464 1465 charset_4="4" 1466 1467 fi 1468 1469 # unique and remove new lines 1470 1471 charset_1=$(echo "${charset_1}" | sort -u | tr -d '\n') 1472 charset_2=$(echo "${charset_2}" | sort -u | tr -d '\n') 1473 charset_3=$(echo "${charset_3}" | sort -u | tr -d '\n') 1474 charset_4=$(echo "${charset_4}" | sort -u | tr -d '\n') 1475 1476 custom_charsets="-1 ${charset_1} -2 ${charset_2} -3 ${charset_3} -4 ${charset_4}" 1477 fi 1478 1479 increment_charset_opts="" 1480 1481 if [ ${need_hcmask} -eq 0 ]; then # the "normal" case without .hcmask file 1482 increment_charset_opts="--increment --increment-min ${increment_min} --increment-max ${increment_max}" 1483 1484 if [ -n "${custom_charsets}" ]; then 1485 increment_charset_opts="${increment_charset_opts} ${custom_charsets}" 1486 fi 1487 fi 1488 1489 CMD="./${BIN} ${OPTS} -a 3 -m ${hash_type} ${increment_charset_opts} ${hash_file} ${mask} " 1490 1491 echo "> Testing hash type $hash_type with attack mode 3, markov ${MARKOV}, multi hash, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}." >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 1492 1493 output=$(./${BIN} ${OPTS} -a 3 -m ${hash_type} ${increment_charset_opts} ${hash_file} ${mask} 2>&1) 1494 1495 ret=${?} 1496 1497 echo "${output}" >> "${OUTD}/logfull.txt" 1498 1499 if [ "${ret}" -eq 0 ]; then 1500 1501 i=1 1502 1503 while read -r -u 9 hash; do 1504 line_nr=$((i + cracks_offset)) 1505 1506 pass=$(sed -n ${line_nr}p "${OUTD}/${hash_type}_passwords.txt") 1507 1508 if [ "${pass_only}" -eq 1 ]; then 1509 search=":${pass}" 1510 else 1511 search="${hash}:${pass}" 1512 fi 1513 1514 echo "${output}" | grep -F "${search}" >/dev/null 2>/dev/null 1515 1516 if [ "${?}" -ne 0 ]; then 1517 1518 ret=10 1519 1520 break 1521 1522 fi 1523 1524 i=$((i + 1)) 1525 1526 done 9< "${OUTD}/${hash_type}_multihash_bruteforce.txt" 1527 1528 fi 1529 1530 status ${ret} 1531 1532 msg="OK" 1533 1534 if [ "${e_nf}" -ne 0 ] || [ "${e_nm}" -ne 0 ]; then 1535 1536 msg="Error" 1537 1538 elif [ "${e_to}" -ne 0 ]; then 1539 1540 msg="Warning" 1541 1542 fi 1543 1544 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 3, Mode multi, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout" 1545 1546 fi 1547} 1548 1549function attack_6() 1550{ 1551 file_only=0 1552 1553 if is_in_array "${hash_type}" ${FILE_BASED_ALGOS}; then 1554 1555 file_only=1 1556 1557 fi 1558 1559 # single hash 1560 if [ "${MODE}" -ne 1 ]; then 1561 1562 e_to=0 1563 e_nf=0 1564 e_nm=0 1565 cnt=0 1566 1567 echo "> Testing hash type $hash_type with attack mode 6, markov ${MARKOV}, single hash, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}." >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 1568 1569 min=1 1570 max=8 1571 mask_offset=0 1572 1573 if [ "${hash_type}" -eq 2500 ]; then 1574 max=6 1575 elif [ "${hash_type}" -eq 14000 ]; then 1576 min=0 1577 max=1 1578 mask_offset=4 1579 elif [ "${hash_type}" -eq 14100 ]; then 1580 min=0 1581 max=1 1582 mask_offset=21 1583 elif [ "${hash_type}" -eq 14900 ]; then 1584 min=0 1585 max=1 1586 mask_offset=5 1587 elif [ "${hash_type}" -eq 15400 ]; then 1588 min=0 1589 max=1 1590 mask_offset=29 1591 elif [ "${hash_type}" -eq 16800 ]; then 1592 max=6 1593 elif [ "${hash_type}" -eq 22000 ]; then 1594 max=6 1595 fi 1596 1597 # special case: we need to split the first line 1598 1599 if [ "${min}" -eq 0 ]; then 1600 1601 pass_part_1=$(sed -n 1p "${OUTD}/${hash_type}_dict1") 1602 pass_part_2=$(sed -n 1p "${OUTD}/${hash_type}_dict2") 1603 1604 pass="${pass_part_1}${pass_part_2}" 1605 1606 echo -n "${pass}" | cut -b -$((mask_offset + 0)) > "${OUTD}/${hash_type}_dict1_custom" 1607 echo -n "${pass}" | cut -b $((mask_offset + 1))- > "${OUTD}/${hash_type}_dict2_custom" 1608 1609 mask_custom="" 1610 1611 for i in $(seq 1 $((${#pass} - mask_offset))); do 1612 1613 if [ "${hash_type}" -eq 14000 ]; then 1614 1615 char=$(echo -n "${pass}" | cut -b $((i + mask_offset))) 1616 mask_custom="${mask_custom}${char}" 1617 1618 elif [ "${hash_type}" -eq 14100 ]; then 1619 1620 char=$(echo -n "${pass}" | cut -b $((i + mask_offset))) 1621 mask_custom="${mask_custom}${char}" 1622 1623 else 1624 1625 mask_custom="${mask_custom}?d" 1626 1627 fi 1628 1629 done 1630 1631 fi 1632 1633 1634 i=1 1635 1636 while read -r -u 9 hash; do 1637 1638 if [ "${i}" -gt 6 ]; then 1639 1640 if is_in_array "${hash_type}" ${TIMEOUT_ALGOS}; then 1641 1642 break 1643 1644 fi 1645 1646 fi 1647 1648 if [ ${i} -gt ${min} ]; then 1649 1650 if [ "${file_only}" -eq 1 ]; then 1651 1652 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt" 1653 1654 if [ "${hash_type}" -ne 22000 ]; then 1655 echo "${hash}" | base64 -d > "${temp_file}" 1656 else 1657 echo "${hash}" > "${temp_file}" 1658 fi 1659 1660 hash="${temp_file}" 1661 1662 fi 1663 1664 dict1=${OUTD}/${hash_type}_dict1 1665 dict2=${OUTD}/${hash_type}_dict2 1666 1667 dict1_a6=${OUTD}/${hash_type}_dict1_a6 1668 1669 cp "${dict1}" "${dict1_a6}" 1670 1671 pass=$(sed -n ${i}p "${OUTD}/${hash_type}_passwords.txt") 1672 1673 if [ "${hash_type}" -eq 20510 ]; then # special case for PKZIP Master Key 1674 pass=$(echo "${pass}" | cut -b 7-) # skip the first 6 chars 1675 fi 1676 1677 if [ ${#pass} -le ${i} ]; then 1678 i=$((i + 1)) 1679 continue 1680 fi 1681 1682 echo "${pass}" | cut -b -$((${#pass} - i)) >> "${dict1_a6}" 1683 1684 # the block below is just a fancy way to do a "shuf" (or sort -R) because macOS doesn't really support it natively 1685 # we do not really need a shuf, but it's actually better for testing purposes 1686 1687 rm -f "${dict1_a6}.txt" # temporary file 1688 1689 line_num=$(wc -l "${dict1_a6}" | sed -E 's/ *([0-9]+) .*$/\1/') 1690 1691 sorted_lines=$(seq 1 "${line_num}") 1692 1693 for lines in $(seq 1 "${line_num}"); do 1694 1695 random_num=$((RANDOM % line_num)) 1696 random_num=$((random_num + 1)) # sed -n [n]p starts counting with 1 (not 0) 1697 1698 random_line=$(echo -n "${sorted_lines}" | sed -n ${random_num}p) 1699 1700 sed -n ${random_line}p "${dict1_a6}" >> "${dict1_a6}.txt" 1701 1702 # update the temp list of lines 1703 1704 sorted_lines=$(echo -n "${sorted_lines}" | grep -v "^${random_line}$") 1705 1706 line_num=$((line_num - 1)) 1707 1708 done 1709 1710 mv "${dict1_a6}.txt" "${dict1_a6}" 1711 1712 # end of shuf/sort -R 1713 1714 1715 mask="" 1716 1717 for j in $(seq 1 ${i}); do 1718 mask="${mask}?d" 1719 done 1720 1721 CMD="./${BIN} ${OPTS} -a 6 -m ${hash_type} '${hash}' ${dict1_a6} ${mask}" 1722 1723 echo -n "[ len $i ] " >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 1724 1725 output=$(./${BIN} ${OPTS} -a 6 -m ${hash_type} "${hash}" ${dict1_a6} ${mask} 2>&1) 1726 1727 ret=${?} 1728 1729 echo "${output}" >> "${OUTD}/logfull.txt" 1730 1731 if [ "${ret}" -eq 0 ]; then 1732 1733 line_nr=1 1734 1735 if [ "${i}" -gt 1 ]; then 1736 line_nr=$((i - 1)) 1737 fi 1738 1739 line_dict1=$(sed -n ${line_nr}p "${dict1}") 1740 line_dict2=$(sed -n ${line_nr}p "${dict2}") 1741 1742 if [ "${pass_only}" -eq 1 ]; then 1743 search=":${line_dict1}${line_dict2}" 1744 else 1745 search="${hash}:${line_dict1}${line_dict2}" 1746 fi 1747 1748 echo "${output}" | grep -F "${search}" >/dev/null 2>/dev/null 1749 1750 if [ "${?}" -ne 0 ]; then 1751 1752 ret=10 1753 1754 fi 1755 1756 fi 1757 1758 status ${ret} 1759 1760 fi 1761 1762 if [ "${i}" -eq ${max} ]; then break; fi 1763 1764 i=$((i + 1)) 1765 1766 done 9< "${OUTD}/${hash_type}_hashes.txt" 1767 1768 msg="OK" 1769 1770 if [ "${e_nf}" -ne 0 ] || [ "${e_nm}" -ne 0 ]; then 1771 1772 msg="Error" 1773 1774 elif [ "${e_to}" -ne 0 ]; then 1775 1776 msg="Warning" 1777 1778 fi 1779 1780 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 6, Mode single, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout" 1781 1782 rm -f "${OUTD}/${hash_type}_dict1_custom" 1783 rm -f "${OUTD}/${hash_type}_dict2_custom" 1784 1785 fi 1786 1787 # multihash 1788 if [ "${MODE}" -ne 0 ]; then 1789 1790 # no multi hash checks for these modes (because we only have 1 hash for each of them) 1791 1792 if [ "${hash_type}" -eq 14000 ]; then 1793 return 1794 elif [ "${hash_type}" -eq 14100 ]; then 1795 return 1796 elif [ "${hash_type}" -eq 14900 ]; then 1797 return 1798 elif [ "${hash_type}" -eq 15400 ]; then 1799 return 1800 fi 1801 1802 e_to=0 1803 e_nf=0 1804 e_nm=0 1805 cnt=0 1806 1807 max=9 1808 1809 if [ "${hash_type}" -eq 2500 ]; then 1810 max=5 1811 elif [ "${hash_type}" -eq 3000 ]; then 1812 max=8 1813 elif [ "${hash_type}" -eq 7700 ] || [ "${hash_type}" -eq 7701 ]; then 1814 max=8 1815 elif [ "${hash_type}" -eq 8500 ]; then 1816 max=8 1817 elif [ "${hash_type}" -eq 16800 ]; then 1818 max=5 1819 elif [ "${hash_type}" -eq 22000 ]; then 1820 max=5 1821 fi 1822 1823 if is_in_array "${hash_type}" ${TIMEOUT_ALGOS}; then 1824 1825 max=5 1826 1827 if [ "${hash_type}" -eq 3200 ]; then 1828 1829 max=3 1830 1831 fi 1832 1833 fi 1834 1835 i=2 1836 while [ "$i" -lt "$max" ]; do 1837 1838 hash_file=${OUTD}/${hash_type}_hashes_multi_${i}.txt 1839 1840 # if file_only -> decode all base64 "hashes" and put them in the temporary file 1841 1842 if [ "${file_only}" -eq 1 ]; then 1843 1844 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt" 1845 rm -f "${temp_file}" 1846 1847 hash_file=${temp_file} 1848 1849 while read -r file_only_hash; do 1850 1851 if [ "${hash_type}" -ne 22000 ]; then 1852 echo -n "${file_only_hash}" | base64 -d >> "${temp_file}" 1853 else 1854 echo "${file_only_hash}" >> "${temp_file}" 1855 fi 1856 1857 done < "${OUTD}/${hash_type}_hashes_multi_${i}.txt" 1858 1859 fi 1860 1861 mask=${mask_6[$i]} 1862 1863 CMD="./${BIN} ${OPTS} -a 6 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1_multi_${i} ${mask}" 1864 1865 echo "> Testing hash type $hash_type with attack mode 6, markov ${MARKOV}, multi hash with word len ${i}." >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 1866 1867 output=$(./${BIN} ${OPTS} -a 6 -m ${hash_type} ${hash_file} ${OUTD}/${hash_type}_dict1_multi_${i} ${mask} 2>&1) 1868 1869 ret=${?} 1870 1871 echo "${output}" >> "${OUTD}/logfull.txt" 1872 1873 if [ "${ret}" -eq 0 ]; then 1874 1875 j=1 1876 1877 while read -r -u 9 hash; do 1878 1879 line_dict1=$(sed -n ${j}p "${OUTD}/${hash_type}_dict1_multi_${i}") 1880 line_dict2=$(sed -n ${j}p "${OUTD}/${hash_type}_dict2_multi_${i}") 1881 1882 if [ "${pass_only}" -eq 1 ]; then 1883 search=":${line_dict1}${line_dict2}" 1884 else 1885 search="${hash}:${line_dict1}${line_dict2}" 1886 fi 1887 1888 echo "${output}" | grep -F "${search}" >/dev/null 2>/dev/null 1889 1890 if [ "${?}" -ne 0 ]; then 1891 1892 ret=10 1893 1894 break 1895 1896 fi 1897 1898 j=$((j + 1)) 1899 1900 done 9< "${OUTD}/${hash_type}_hashes_multi_${i}.txt" 1901 1902 fi 1903 1904 status ${ret} 1905 i=$((i + 1)) 1906 1907 done 1908 1909 msg="OK" 1910 1911 if [ "${e_nf}" -ne 0 ] || [ "${e_nm}" -ne 0 ]; then 1912 1913 msg="Error" 1914 1915 elif [ "${e_to}" -ne 0 ]; then 1916 1917 msg="Warning" 1918 1919 fi 1920 1921 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 6, Mode multi, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout" 1922 1923 fi 1924} 1925 1926function attack_7() 1927{ 1928 file_only=0 1929 1930 if is_in_array "${hash_type}" ${FILE_BASED_ALGOS}; then 1931 1932 file_only=1 1933 1934 fi 1935 1936 # single hash 1937 if [ "${MODE}" -ne 1 ]; then 1938 1939 e_to=0 1940 e_nf=0 1941 e_nm=0 1942 cnt=0 1943 1944 echo "> Testing hash type $hash_type with attack mode 7, markov ${MARKOV}, single hash, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}." >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 1945 1946 min=1 1947 max=8 1948 1949 mask_offset=0 1950 1951 if [ "${hash_type}" -eq 2500 ]; then 1952 max=5 1953 elif [ "${hash_type}" -eq 14000 ]; then 1954 mask_offset=4 1955 min=0 1956 max=1 1957 elif [ "${hash_type}" -eq 14100 ]; then 1958 mask_offset=3 1959 min=0 1960 max=1 1961 elif [ "${hash_type}" -eq 14900 ]; then 1962 mask_offset=5 1963 min=0 1964 max=1 1965 elif [ "${hash_type}" -eq 15400 ]; then 1966 mask_offset=3 1967 min=0 1968 max=1 1969 elif [ "${hash_type}" -eq 16800 ]; then 1970 max=5 1971 elif [ "${hash_type}" -eq 22000 ]; then 1972 max=5 1973 fi 1974 1975 # special case: we need to split the first line 1976 1977 if [ "${min}" -eq 0 ]; then 1978 1979 pass_part_1=$(sed -n 1p "${OUTD}/${hash_type}_dict1") 1980 pass_part_2=$(sed -n 1p "${OUTD}/${hash_type}_dict2") 1981 1982 pass="${pass_part_1}${pass_part_2}" 1983 1984 echo -n "${pass}" | cut -b -$((mask_offset + 0)) > "${OUTD}/${hash_type}_dict1_custom" 1985 echo -n "${pass}" | cut -b $((mask_offset + 1))- > "${OUTD}/${hash_type}_dict2_custom" 1986 1987 mask_custom="" 1988 1989 for i in $(seq 1 ${mask_offset}); do 1990 1991 if [ "${hash_type}" -eq 14000 ]; then 1992 1993 char=$(echo -n "${pass}" | cut -b ${i}) 1994 mask_custom="${mask_custom}${char}" 1995 1996 elif [ "${hash_type}" -eq 14100 ]; then 1997 1998 char=$(echo -n "${pass}" | cut -b ${i}) 1999 mask_custom="${mask_custom}${char}" 2000 2001 else 2002 2003 mask_custom="${mask_custom}?d" 2004 2005 fi 2006 2007 done 2008 2009 fi 2010 2011 i=1 2012 2013 while read -r -u 9 hash; do 2014 2015 if [ ${i} -gt ${min} ]; then 2016 2017 if [ "${file_only}" -eq 1 ]; then 2018 2019 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt" 2020 2021 if [ "${hash_type}" -ne 22000 ]; then 2022 echo "${hash}" | base64 -d > "${temp_file}" 2023 else 2024 echo "${hash}" > "${temp_file}" 2025 fi 2026 2027 hash="${temp_file}" 2028 2029 fi 2030 2031 mask=${mask_7[$i]} 2032 2033 # adjust mask if needed 2034 2035 line_nr=1 2036 2037 if [ "${i}" -gt 1 ]; then 2038 line_nr=$((i - 1)) 2039 fi 2040 2041 if [ "${hash_type}" -eq 2500 ]; then 2042 2043 pass_part_1=$(sed -n ${line_nr}p "${OUTD}/${hash_type}_dict1") 2044 pass_part_2=$(sed -n ${line_nr}p "${OUTD}/${hash_type}_dict2") 2045 2046 pass_part_2_len=${#pass_part_2} 2047 2048 pass=${pass_part_1}${pass_part_2} 2049 2050 pass_len=${#pass} 2051 2052 # add first x chars of password to mask and append the (old) mask 2053 2054 mask_len=${#mask} 2055 mask_len=$((mask_len / 2)) 2056 2057 mask_prefix=$(echo ${pass} | cut -b -$((pass_len - mask_len - pass_part_2_len))) 2058 mask=${mask_prefix}${mask} 2059 2060 fi 2061 2062 if [ "${hash_type}" -eq 16800 ]; then 2063 2064 pass_part_1=$(sed -n ${line_nr}p "${OUTD}/${hash_type}_dict1") 2065 pass_part_2=$(sed -n ${line_nr}p "${OUTD}/${hash_type}_dict2") 2066 2067 pass_part_2_len=${#pass_part_2} 2068 2069 pass=${pass_part_1}${pass_part_2} 2070 pass_len=${#pass} 2071 2072 # add first x chars of password to mask and append the (old) mask 2073 2074 mask_len=${#mask} 2075 mask_len=$((mask_len / 2)) 2076 2077 mask_prefix=$(echo "${pass}" | cut -b -$((pass_len - mask_len - pass_part_2_len))) 2078 mask=${mask_prefix}${mask} 2079 2080 fi 2081 2082 if [ "${hash_type}" -eq 22000 ]; then 2083 2084 pass_part_1=$(sed -n ${line_nr}p "${OUTD}/${hash_type}_dict1") 2085 pass_part_2=$(sed -n ${line_nr}p "${OUTD}/${hash_type}_dict2") 2086 2087 pass_part_2_len=${#pass_part_2} 2088 2089 pass=${pass_part_1}${pass_part_2} 2090 pass_len=${#pass} 2091 2092 # add first x chars of password to mask and append the (old) mask 2093 2094 mask_len=${#mask} 2095 mask_len=$((mask_len / 2)) 2096 2097 mask_prefix=$(echo "${pass}" | cut -b -$((pass_len - mask_len - pass_part_2_len))) 2098 mask=${mask_prefix}${mask} 2099 2100 fi 2101 2102 if [ "${hash_type}" -eq 20510 ]; then 2103 2104 pass_part_1=$(sed -n ${line_nr}p "${OUTD}/${hash_type}_dict1") 2105 pass_part_2=$(sed -n ${line_nr}p "${OUTD}/${hash_type}_dict2") 2106 2107 pass=${pass_part_1}${pass_part_2} 2108 2109 pass_len=${#pass} 2110 2111 if [ "${pass_len}" -le 6 ]; then 2112 i=$((i + 1)) 2113 continue 2114 fi 2115 2116 pass_old=${pass} 2117 2118 pass=$(echo "${pass}" | cut -b 7-) # skip the first 6 chars 2119 2120 mask_len=$((${#mask} / 2)) 2121 2122 echo "${pass_old}" | cut -b -$((6 + mask_len)) > "${OUTD}/${hash_type}_dict1_custom" 2123 echo "${pass}" | cut -b $((mask_len + 1))- > "${OUTD}/${hash_type}_dict2_custom" 2124 2125 min=0 # hack to use the custom dict 2126 mask_custom=${mask} 2127 2128 fi 2129 2130 dict1=${OUTD}/${hash_type}_dict1 2131 dict2=${OUTD}/${hash_type}_dict2 2132 2133 if [ "${min}" -eq 0 ]; then 2134 mask=${mask_custom} 2135 2136 dict1=${OUTD}/${hash_type}_dict1_custom 2137 dict2=${OUTD}/${hash_type}_dict2_custom 2138 fi 2139 2140 CMD="./${BIN} ${OPTS} -a 7 -m ${hash_type} '${hash}' ${mask} ${dict2}" 2141 2142 echo -n "[ len $i ] " >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 2143 2144 output=$(./${BIN} ${OPTS} -a 7 -m ${hash_type} "${hash}" ${mask} ${dict2} 2>&1) 2145 2146 ret=${?} 2147 2148 echo "${output}" >> "${OUTD}/logfull.txt" 2149 2150 if [ "${ret}" -eq 0 ]; then 2151 2152 line_nr=1 2153 2154 if [ "${i}" -gt 1 ]; then 2155 line_nr=$((i - 1)) 2156 fi 2157 2158 line_dict1=$(sed -n ${line_nr}p "${dict1}") 2159 line_dict2=$(sed -n ${line_nr}p "${dict2}") 2160 2161 if [ "${pass_only}" -eq 1 ]; then 2162 search=":${line_dict1}${line_dict2}" 2163 else 2164 search="${hash}:${line_dict1}${line_dict2}" 2165 fi 2166 2167 echo "${output}" | grep -F "${search}" >/dev/null 2>/dev/null 2168 2169 if [ "${?}" -ne 0 ]; then 2170 2171 ret=10 2172 2173 fi 2174 2175 fi 2176 2177 status ${ret} 2178 2179 fi 2180 2181 if [ $i -eq ${max} ]; then break; fi 2182 2183 i=$((i + 1)) 2184 2185 done 9< "${OUTD}/${hash_type}_hashes.txt" 2186 2187 msg="OK" 2188 2189 if [ "${e_nf}" -ne 0 ] || [ "${e_nm}" -ne 0 ]; then 2190 2191 msg="Error" 2192 2193 elif [ "${e_to}" -ne 0 ]; then 2194 2195 msg="Warning" 2196 2197 fi 2198 2199 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 7, Mode single, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout" 2200 2201 rm -f "${OUTD}/${hash_type}_dict1_custom" 2202 rm -f "${OUTD}/${hash_type}_dict2_custom" 2203 2204 fi 2205 2206 # multihash 2207 if [ "${MODE}" -ne 0 ]; then 2208 2209 # no multi hash checks for these modes (because we only have 1 hash for each of them) 2210 2211 if [ "${hash_type}" -eq 14000 ]; then 2212 return 2213 elif [ "${hash_type}" -eq 14100 ]; then 2214 return 2215 elif [ "${hash_type}" -eq 14900 ]; then 2216 return 2217 elif [ "${hash_type}" -eq 15400 ]; then 2218 return 2219 fi 2220 2221 e_to=0 2222 e_nf=0 2223 e_nm=0 2224 cnt=0 2225 2226 max=9 2227 2228 if [ "${hash_type}" -eq 2500 ]; then 2229 max=5 2230 elif [ "${hash_type}" -eq 3000 ]; then 2231 max=8 2232 elif [ "${hash_type}" -eq 7700 ] || [ "${hash_type}" -eq 7701 ]; then 2233 max=8 2234 elif [ "${hash_type}" -eq 8500 ]; then 2235 max=8 2236 elif [ "${hash_type}" -eq 14000 ]; then 2237 max=5 2238 elif [ "${hash_type}" -eq 14100 ]; then 2239 max=5 2240 elif [ "${hash_type}" -eq 14900 ]; then 2241 max=5 2242 elif [ "${hash_type}" -eq 15400 ]; then 2243 max=5 2244 elif [ "${hash_type}" -eq 16800 ]; then 2245 max=5 2246 elif [ "${hash_type}" -eq 22000 ]; then 2247 max=5 2248 fi 2249 2250 if is_in_array "${hash_type}" ${TIMEOUT_ALGOS}; then 2251 2252 max=7 2253 2254 if [ "${hash_type}" -eq 3200 ]; then 2255 2256 max=4 2257 2258 fi 2259 2260 fi 2261 2262 i=2 2263 while [ "$i" -lt "$max" ]; do 2264 2265 hash_file=${OUTD}/${hash_type}_hashes_multi_${i}.txt 2266 dict_file=${OUTD}/${hash_type}_dict2_multi_${i} 2267 2268 mask=${mask_7[$i]} 2269 2270 # if file_only -> decode all base64 "hashes" and put them in the temporary file 2271 2272 if [ "${file_only}" -eq 1 ]; then 2273 2274 temp_file="${OUTD}/${hash_type}_filebased_only_temp.txt" 2275 rm -f "${temp_file}" 2276 2277 hash_file=${temp_file} 2278 2279 while read -r file_only_hash; do 2280 2281 if [ "${hash_type}" -ne 22000 ]; then 2282 echo -n "${file_only_hash}" | base64 -d >> "${temp_file}" 2283 else 2284 echo "${file_only_hash}" >> "${temp_file}" 2285 fi 2286 2287 done < "${OUTD}/${hash_type}_hashes_multi_${i}.txt" 2288 2289 # a little hack: since we don't want to have a very large mask (and wpa has minimum length of 8), 2290 # we need to create a temporary dict file on-the-fly and use it like this: [small mask] [long(er) words in dict] 2291 2292 dict_file=${OUTD}/${hash_type}_dict2_multi_${i}_longer 2293 rm -f "${dict_file}" 2294 2295 mask_len=${#mask} 2296 mask_len=$((mask_len / 2)) 2297 2298 j=1 2299 2300 while read -r -u 9 hash; do 2301 2302 pass_part_1=$(sed -n ${j}p "${OUTD}/${hash_type}_dict1_multi_${i}") 2303 pass_part_2=$(sed -n ${j}p "${OUTD}/${hash_type}_dict2_multi_${i}") 2304 2305 pass="${pass_part_1}${pass_part_2}" 2306 2307 pass_suffix=$(echo "${pass}" | cut -b $((mask_len + 1))-) 2308 2309 echo "${pass_suffix}" >> "${dict_file}" 2310 2311 j=$((j + 1)) 2312 2313 done 9< "${OUTD}/${hash_type}_hashes_multi_${i}.txt" 2314 2315 fi 2316 2317 CMD="./${BIN} ${OPTS} -a 7 -m ${hash_type} ${hash_file} ${mask} ${dict_file}" 2318 2319 echo "> Testing hash type $hash_type with attack mode 7, markov ${MARKOV}, multi hash with word len ${i}." >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 2320 2321 output=$(./${BIN} ${OPTS} -a 7 -m ${hash_type} ${hash_file} ${mask} ${dict_file} 2>&1) 2322 2323 ret=${?} 2324 2325 echo "${output}" >> "${OUTD}/logfull.txt" 2326 2327 if [ "${ret}" -eq 0 ]; then 2328 2329 j=1 2330 2331 while read -r -u 9 hash; do 2332 2333 line_dict1=$(sed -n ${j}p "${OUTD}/${hash_type}_dict1_multi_${i}") 2334 line_dict2=$(sed -n ${j}p "${OUTD}/${hash_type}_dict2_multi_${i}") 2335 2336 if [ "${pass_only}" -eq 1 ]; then 2337 search=":${line_dict1}${line_dict2}" 2338 else 2339 search="${hash}:${line_dict1}${line_dict2}" 2340 fi 2341 2342 echo "${output}" | grep -F "${search}" >/dev/null 2>/dev/null 2343 2344 if [ "${?}" -ne 0 ]; then 2345 2346 ret=10 2347 2348 break 2349 2350 fi 2351 2352 j=$((j + 1)) 2353 2354 done 9< "${OUTD}/${hash_type}_hashes_multi_${i}.txt" 2355 2356 fi 2357 2358 status ${ret} 2359 i=$((i + 1)) 2360 2361 done 2362 2363 msg="OK" 2364 2365 if [ "${e_nf}" -ne 0 ] || [ "${e_nm}" -ne 0 ]; then 2366 2367 msg="Error" 2368 2369 elif [ "${e_to}" -ne 0 ]; then 2370 2371 msg="Warning" 2372 2373 fi 2374 2375 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 7, Mode multi, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR} ] > $msg : ${e_nf}/${cnt} not found, ${e_nm}/${cnt} not matched, ${e_to}/${cnt} timeout" 2376 2377 fi 2378} 2379 2380function cryptoloop_test() 2381{ 2382 hashType=$1 2383 keySize=$2 2384 CMD="unset" 2385 2386 mkdir -p ${OUTD}/cl_tests 2387 chmod u+x ${TDIR}/cryptoloop2hashcat.py 2388 2389 case $hashType in 2390 2391 14511) 2392 case $keySize in 2393 128|192|256) 2394 ${TDIR}/cryptoloop2hashcat.py --source ${TDIR}/cl_tests/hashcat_sha1_aes_${keySize}.img --hash sha1 --cipher aes --keysize ${keySize} > ${OUTD}/cl_tests/hashcat_sha1_aes_${keySize}.hash 2395 CMD="./${BIN} ${OPTS} -a 3 -m 14500 ${OUTD}/cl_tests/hashcat_sha1_aes_${keySize}.hash hashca?l" 2396 ;; 2397 esac 2398 ;; 2399 2400 14512) 2401 case $keySize in 2402 128|192|256) 2403 ${TDIR}/cryptoloop2hashcat.py --source ${TDIR}/cl_tests/hashcat_sha1_serpent_${keySize}.img --hash sha1 --cipher serpent --keysize ${keySize} > ${OUTD}/cl_tests/hashcat_sha1_serpent_${keySize}.hash 2404 CMD="./${BIN} ${OPTS} -a 3 -m 14500 ${OUTD}/cl_tests/hashcat_sha1_serpent_${keySize}.hash hashca?l" 2405 ;; 2406 esac 2407 ;; 2408 2409 14513) 2410 case $keySize in 2411 128|192|256) 2412 ${TDIR}/cryptoloop2hashcat.py --source ${TDIR}/cl_tests/hashcat_sha1_twofish_${keySize}.img --hash sha1 --cipher twofish --keysize ${keySize} > ${OUTD}/cl_tests/hashcat_sha1_twofish_${keySize}.hash 2413 CMD="./${BIN} ${OPTS} -a 3 -m 14500 ${OUTD}/cl_tests/hashcat_sha1_twofish_${keySize}.hash hashca?l" 2414 ;; 2415 esac 2416 ;; 2417 2418 14521) 2419 case $keySize in 2420 128|192|256) 2421 ${TDIR}/cryptoloop2hashcat.py --source ${TDIR}/cl_tests/hashcat_sha256_aes_${keySize}.img --hash sha256 --cipher aes --keysize ${keySize} > ${OUTD}/cl_tests/hashcat_sha256_aes_${keySize}.hash 2422 CMD="./${BIN} ${OPTS} -a 3 -m 14500 ${OUTD}/cl_tests/hashcat_sha256_aes_${keySize}.hash hashca?l" 2423 ;; 2424 esac 2425 ;; 2426 2427 14522) 2428 case $keySize in 2429 128|192|256) 2430 ${TDIR}/cryptoloop2hashcat.py --source ${TDIR}/cl_tests/hashcat_sha256_serpent_${keySize}.img --hash sha256 --cipher serpent --keysize ${keySize} > ${OUTD}/cl_tests/hashcat_sha256_serpent_${keySize}.hash 2431 CMD="./${BIN} ${OPTS} -a 3 -m 14500 ${OUTD}/cl_tests/hashcat_sha256_serpent_${keySize}.hash hashca?l" 2432 ;; 2433 esac 2434 ;; 2435 2436 14523) 2437 case $keySize in 2438 128|192|256) 2439 ${TDIR}/cryptoloop2hashcat.py --source ${TDIR}/cl_tests/hashcat_sha256_twofish_${keySize}.img --hash sha256 --cipher twofish --keysize ${keySize} > ${OUTD}/cl_tests/hashcat_sha256_twofish_${keySize}.hash 2440 CMD="./${BIN} ${OPTS} -a 3 -m 14500 ${OUTD}/cl_tests/hashcat_sha256_twofish_${keySize}.hash hashca?l" 2441 ;; 2442 esac 2443 ;; 2444 2445 14531) 2446 case $keySize in 2447 128|192|256) 2448 ${TDIR}/cryptoloop2hashcat.py --source ${TDIR}/cl_tests/hashcat_sha512_aes_${keySize}.img --hash sha512 --cipher aes --keysize ${keySize} > ${OUTD}/cl_tests/hashcat_sha512_aes_${keySize}.hash 2449 CMD="./${BIN} ${OPTS} -a 3 -m 14500 ${OUTD}/cl_tests/hashcat_sha512_aes_${keySize}.hash hashca?l" 2450 ;; 2451 esac 2452 ;; 2453 2454 14532) 2455 case $keySize in 2456 128|192|256) 2457 ${TDIR}/cryptoloop2hashcat.py --source ${TDIR}/cl_tests/hashcat_sha512_serpent_${keySize}.img --hash sha512 --cipher serpent --keysize ${keySize} > ${OUTD}/cl_tests/hashcat_sha512_serpent_${keySize}.hash 2458 CMD="./${BIN} ${OPTS} -a 3 -m 14500 ${OUTD}/cl_tests/hashcat_sha512_serpent_${keySize}.hash hashca?l" 2459 ;; 2460 esac 2461 ;; 2462 2463 14533) 2464 case $keySize in 2465 128|192|256) 2466 ${TDIR}/cryptoloop2hashcat.py --source ${TDIR}/cl_tests/hashcat_sha512_twofish_${keySize}.img --hash sha512 --cipher twofish --keysize ${keySize} > ${OUTD}/cl_tests/hashcat_sha512_twofish_${keySize}.hash 2467 CMD="./${BIN} ${OPTS} -a 3 -m 14500 ${OUTD}/cl_tests/hashcat_sha512_twofish_${keySize}.hash hashca?l" 2468 ;; 2469 esac 2470 ;; 2471 2472 14541) 2473 case $keySize in 2474 128|192|256) 2475 ${TDIR}/cryptoloop2hashcat.py --source ${TDIR}/cl_tests/hashcat_ripemd160_aes_${keySize}.img --hash ripemd160 --cipher aes --keysize ${keySize} > ${OUTD}/cl_tests/hashcat_ripemd160_aes_${keySize}.hash 2476 CMD="./${BIN} ${OPTS} -a 3 -m 14500 ${OUTD}/cl_tests/hashcat_ripemd160_aes_${keySize}.hash hashca?l" 2477 ;; 2478 esac 2479 ;; 2480 2481 14542) 2482 case $keySize in 2483 128|192|256) 2484 ${TDIR}/cryptoloop2hashcat.py --source ${TDIR}/cl_tests/hashcat_ripemd160_serpent_${keySize}.img --hash ripemd160 --cipher serpent --keysize ${keySize} > ${OUTD}/cl_tests/hashcat_ripemd160_serpent_${keySize}.hash 2485 CMD="./${BIN} ${OPTS} -a 3 -m 14500 ${OUTD}/cl_tests/hashcat_ripemd160_serpent_${keySize}.hash hashca?l" 2486 ;; 2487 esac 2488 ;; 2489 2490 14543) 2491 case $keySize in 2492 128|192|256) 2493 ${TDIR}/cryptoloop2hashcat.py --source ${TDIR}/cl_tests/hashcat_ripemd160_twofish_${keySize}.img --hash ripemd160 --cipher twofish --keysize ${keySize} > ${OUTD}/cl_tests/hashcat_ripemd160_twofish_${keySize}.hash 2494 CMD="./${BIN} ${OPTS} -a 3 -m 14500 ${OUTD}/cl_tests/hashcat_ripemd160_twofish_${keySize}.hash hashca?l" 2495 ;; 2496 esac 2497 ;; 2498 2499 14551) 2500 case $keySize in 2501 128|192|256) 2502 ${TDIR}/cryptoloop2hashcat.py --source ${TDIR}/cl_tests/hashcat_whirlpool_aes_${keySize}.img --hash whirlpool --cipher aes --keysize ${keySize} > ${OUTD}/cl_tests/hashcat_whirlpool_aes_${keySize}.hash 2503 CMD="./${BIN} ${OPTS} -a 3 -m 14500 ${OUTD}/cl_tests/hashcat_whirlpool_aes_${keySize}.hash hashca?l" 2504 ;; 2505 esac 2506 ;; 2507 2508 14552) 2509 case $keySize in 2510 128|192|256) 2511 ${TDIR}/cryptoloop2hashcat.py --source ${TDIR}/cl_tests/hashcat_whirlpool_serpent_${keySize}.img --hash whirlpool --cipher serpent --keysize ${keySize} > ${OUTD}/cl_tests/hashcat_whirlpool_serpent_${keySize}.hash 2512 CMD="./${BIN} ${OPTS} -a 3 -m 14500 ${OUTD}/cl_tests/hashcat_whirlpool_serpent_${keySize}.hash hashca?l" 2513 ;; 2514 esac 2515 ;; 2516 2517 14553) 2518 case $keySize in 2519 128|192|256) 2520 ${TDIR}/cryptoloop2hashcat.py --source ${TDIR}/cl_tests/hashcat_whirlpool_twofish_${keySize}.img --hash whirlpool --cipher twofish --keysize ${keySize} > ${OUTD}/cl_tests/hashcat_whirlpool_twofish_${keySize}.hash 2521 CMD="./${BIN} ${OPTS} -a 3 -m 14500 ${OUTD}/cl_tests/hashcat_whirlpool_twofish_${keySize}.hash hashca?l" 2522 ;; 2523 esac 2524 ;; 2525 esac 2526 2527 if [ ${#CMD} -gt 5 ]; then 2528 echo "> Testing hash type $hashType with attack mode 3, markov ${MARKOV}, single hash, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}, Key-Size ${keySize}" >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 2529 2530 output=$(${CMD} 2>&1) 2531 2532 ret=${?} 2533 2534 echo "${output}" >> "${OUTD}/logfull.txt" 2535 2536 cnt=1 2537 e_nf=0 2538 msg="OK" 2539 2540 if [ ${ret} -ne 0 ]; then 2541 e_nf=1 2542 msg="Error" 2543 fi 2544 2545 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 3, Mode single, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}, Key-Size ${keySize} ] > $msg : ${e_nf}/${cnt} not found" 2546 2547 status ${ret} 2548 fi 2549} 2550 2551function truecrypt_test() 2552{ 2553 hashType=$1 2554 tcMode=$2 2555 CMD="unset" 2556 2557 case $hashType in 2558 2559 6211) 2560 case $tcMode in 2561 0) 2562 CMD="./${BIN} ${OPTS} -a 3 -m 6211 ${TDIR}/tc_tests/hashcat_ripemd160_aes.tc hashca?l" 2563 ;; 2564 1) 2565 CMD="./${BIN} ${OPTS} -a 3 -m 6211 ${TDIR}/tc_tests/hashcat_ripemd160_serpent.tc hashca?l" 2566 ;; 2567 2) 2568 CMD="./${BIN} ${OPTS} -a 3 -m 6211 ${TDIR}/tc_tests/hashcat_ripemd160_twofish.tc hashca?l" 2569 ;; 2570 esac 2571 ;; 2572 2573 6212) 2574 case $tcMode in 2575 0) 2576 CMD="./${BIN} ${OPTS} -a 3 -m 6212 ${TDIR}/tc_tests/hashcat_ripemd160_aes-twofish.tc hashca?l" 2577 ;; 2578 1) 2579 CMD="./${BIN} ${OPTS} -a 3 -m 6212 ${TDIR}/tc_tests/hashcat_ripemd160_serpent-aes.tc hashca?l" 2580 ;; 2581 2) 2582 CMD="./${BIN} ${OPTS} -a 3 -m 6212 ${TDIR}/tc_tests/hashcat_ripemd160_twofish-serpent.tc hashca?l" 2583 ;; 2584 esac 2585 ;; 2586 2587 6213) 2588 case $tcMode in 2589 0) 2590 CMD="./${BIN} ${OPTS} -a 3 -m 6213 ${TDIR}/tc_tests/hashcat_ripemd160_aes-twofish-serpent.tc hashca?l" 2591 ;; 2592 1) 2593 CMD="./${BIN} ${OPTS} -a 3 -m 6213 ${TDIR}/tc_tests/hashcat_ripemd160_serpent-twofish-aes.tc hashca?l" 2594 ;; 2595 esac 2596 ;; 2597 2598 6221) 2599 case $tcMode in 2600 0) 2601 CMD="./${BIN} ${OPTS} -a 3 -m 6221 ${TDIR}/tc_tests/hashcat_sha512_aes.tc hashca?l" 2602 ;; 2603 1) 2604 CMD="./${BIN} ${OPTS} -a 3 -m 6221 ${TDIR}/tc_tests/hashcat_sha512_serpent.tc hashca?l" 2605 ;; 2606 2) 2607 CMD="./${BIN} ${OPTS} -a 3 -m 6221 ${TDIR}/tc_tests/hashcat_sha512_twofish.tc hashca?l" 2608 ;; 2609 esac 2610 ;; 2611 2612 6222) 2613 case $tcMode in 2614 0) 2615 CMD="./${BIN} ${OPTS} -a 3 -m 6222 ${TDIR}/tc_tests/hashcat_sha512_aes-twofish.tc hashca?l" 2616 ;; 2617 1) 2618 CMD="./${BIN} ${OPTS} -a 3 -m 6222 ${TDIR}/tc_tests/hashcat_sha512_serpent-aes.tc hashca?l" 2619 ;; 2620 2) 2621 CMD="./${BIN} ${OPTS} -a 3 -m 6222 ${TDIR}/tc_tests/hashcat_sha512_twofish-serpent.tc hashca?l" 2622 ;; 2623 esac 2624 ;; 2625 2626 6223) 2627 case $tcMode in 2628 0) 2629 CMD="./${BIN} ${OPTS} -a 3 -m 6223 ${TDIR}/tc_tests/hashcat_sha512_aes-twofish-serpent.tc hashca?l" 2630 ;; 2631 1) 2632 CMD="./${BIN} ${OPTS} -a 3 -m 6223 ${TDIR}/tc_tests/hashcat_sha512_serpent-twofish-aes.tc hashca?l" 2633 ;; 2634 esac 2635 ;; 2636 2637 6231) 2638 case $tcMode in 2639 0) 2640 CMD="./${BIN} ${OPTS} -a 3 -m 6231 ${TDIR}/tc_tests/hashcat_whirlpool_aes.tc hashca?l" 2641 ;; 2642 1) 2643 CMD="./${BIN} ${OPTS} -a 3 -m 6231 ${TDIR}/tc_tests/hashcat_whirlpool_serpent.tc hashca?l" 2644 ;; 2645 2) 2646 CMD="./${BIN} ${OPTS} -a 3 -m 6231 ${TDIR}/tc_tests/hashcat_whirlpool_twofish.tc hashca?l" 2647 ;; 2648 esac 2649 ;; 2650 2651 6232) 2652 case $tcMode in 2653 0) 2654 CMD="./${BIN} ${OPTS} -a 3 -m 6232 ${TDIR}/tc_tests/hashcat_whirlpool_aes-twofish.tc hashca?l" 2655 ;; 2656 1) 2657 CMD="./${BIN} ${OPTS} -a 3 -m 6232 ${TDIR}/tc_tests/hashcat_whirlpool_serpent-aes.tc hashca?l" 2658 ;; 2659 2) 2660 CMD="./${BIN} ${OPTS} -a 3 -m 6232 ${TDIR}/tc_tests/hashcat_whirlpool_twofish-serpent.tc hashca?l" 2661 ;; 2662 esac 2663 ;; 2664 2665 6233) 2666 case $tcMode in 2667 0) 2668 CMD="./${BIN} ${OPTS} -a 3 -m 6233 ${TDIR}/tc_tests/hashcat_whirlpool_aes-twofish-serpent.tc hashca?l" 2669 ;; 2670 1) 2671 CMD="./${BIN} ${OPTS} -a 3 -m 6233 ${TDIR}/tc_tests/hashcat_whirlpool_serpent-twofish-aes.tc hashca?l" 2672 ;; 2673 esac 2674 ;; 2675 2676 6241) 2677 case $tcMode in 2678 0) 2679 CMD="./${BIN} ${OPTS} -a 3 -m 6241 ${TDIR}/tc_tests/hashcat_ripemd160_aes_boot.tc hashca?l" 2680 ;; 2681 1) 2682 CMD="./${BIN} ${OPTS} -a 3 -m 6241 ${TDIR}/tc_tests/hashcat_ripemd160_serpent_boot.tc hashca?l" 2683 ;; 2684 2) 2685 CMD="./${BIN} ${OPTS} -a 3 -m 6241 ${TDIR}/tc_tests/hashcat_ripemd160_twofish_boot.tc hashca?l" 2686 ;; 2687 esac 2688 ;; 2689 2690 6242) 2691 case $tcMode in 2692 0) 2693 CMD="./${BIN} ${OPTS} -a 3 -m 6242 ${TDIR}/tc_tests/hashcat_ripemd160_aes-twofish_boot.tc hashca?l" 2694 ;; 2695 1) 2696 CMD="./${BIN} ${OPTS} -a 3 -m 6242 ${TDIR}/tc_tests/hashcat_ripemd160_serpent-aes_boot.tc hashca?l" 2697 ;; 2698 esac 2699 ;; 2700 2701 6243) 2702 case $tcMode in 2703 0) 2704 CMD="./${BIN} ${OPTS} -a 3 -m 6243 ${TDIR}/tc_tests/hashcat_ripemd160_aes-twofish-serpent_boot.tc hashca?l" 2705 ;; 2706 esac 2707 ;; 2708 esac 2709 2710 if [ ${#CMD} -gt 5 ]; then 2711 echo "> Testing hash type $hashType with attack mode 3, markov ${MARKOV}, single hash, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}, tcMode ${tcMode}" >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 2712 2713 output=$(${CMD} 2>&1) 2714 2715 ret=${?} 2716 2717 echo "${output}" >> "${OUTD}/logfull.txt" 2718 2719 cnt=1 2720 e_nf=0 2721 msg="OK" 2722 2723 if [ ${ret} -ne 0 ]; then 2724 e_nf=1 2725 msg="Error" 2726 fi 2727 2728 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 3, Mode single, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}, tcMode ${tcMode} ] > $msg : ${e_nf}/${cnt} not found" 2729 2730 status ${ret} 2731 fi 2732} 2733 2734# Compose and execute hashcat command on a VeraCrypt test container 2735# Must not be called for hash types other than 137XY 2736# $1: cipher variation, can be 0-6 2737function veracrypt_test() 2738{ 2739 cipher_variation=$1 2740 2741 hash_function="" 2742 2743 hash_digit="${hash_type:3:1}" 2744 [ "$hash_digit" -eq "1" ] && hash_function="ripemd160" 2745 [ "$hash_digit" -eq "2" ] && hash_function="sha512" 2746 [ "$hash_digit" -eq "3" ] && hash_function="whirlpool" 2747 [ "$hash_digit" -eq "5" ] && hash_function="sha256" 2748 [ "$hash_digit" -eq "7" ] && hash_function="streebog" 2749 2750 [ -n "$hash_function" ] || return 2751 2752 cipher_cascade="" 2753 2754 cipher_digit="${hash_type:4:1}" 2755 case $cipher_digit in 2756 1) 2757 [ "$cipher_variation" -eq "0" ] && cipher_cascade="aes" 2758 [ "$cipher_variation" -eq "1" ] && cipher_cascade="serpent" 2759 [ "$cipher_variation" -eq "2" ] && cipher_cascade="twofish" 2760 [ "$cipher_variation" -eq "3" ] && cipher_cascade="camellia" 2761 [ "$cipher_variation" -eq "5" ] && cipher_cascade="kuznyechik" 2762 ;; 2763 2) 2764 [ "$cipher_variation" -eq "0" ] && cipher_cascade="aes-twofish" 2765 [ "$cipher_variation" -eq "1" ] && cipher_cascade="serpent-aes" 2766 [ "$cipher_variation" -eq "2" ] && cipher_cascade="twofish-serpent" 2767 [ "$cipher_variation" -eq "3" ] && cipher_cascade="camellia-kuznyechik" 2768 [ "$cipher_variation" -eq "4" ] && cipher_cascade="camellia-serpent" 2769 [ "$cipher_variation" -eq "5" ] && cipher_cascade="kuznyechik-aes" 2770 [ "$cipher_variation" -eq "6" ] && cipher_cascade="kuznyechik-twofish" 2771 ;; 2772 3) 2773 [ "$cipher_variation" -eq "0" ] && cipher_cascade="aes-twofish-serpent" 2774 [ "$cipher_variation" -eq "1" ] && cipher_cascade="serpent-twofish-aes" 2775 [ "$cipher_variation" -eq "5" ] && cipher_cascade="kuznyechik-serpent-camellia" 2776 ;; 2777 esac 2778 2779 [ -n "$cipher_cascade" ] || return 2780 2781 filename="${TDIR}/vc_tests/hashcat_${hash_function}_${cipher_cascade}.vc" 2782 2783 # The hash-cipher combination might be invalid (e.g. RIPEMD-160 + Kuznyechik) 2784 [ -f "${filename}" ] || return 2785 2786 CMD="./${BIN} ${OPTS} -a 3 -m ${hash_type} ${filename} hashc?lt" 2787 2788 echo "> Testing hash type ${hash_type} with attack mode 0, markov ${MARKOV}, single hash, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}, Cipher ${cipher_cascade}" >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 2789 2790 output=$(${CMD} 2>&1) 2791 2792 ret=${?} 2793 2794 echo "${output}" >> "${OUTD}/logfull.txt" 2795 2796 cnt=1 2797 e_nf=0 2798 msg="OK" 2799 2800 if [ ${ret} -ne 0 ]; then 2801 e_nf=1 2802 msg="Error" 2803 fi 2804 2805 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack 0, Mode single, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}, Cipher ${cipher_cascade} ] > $msg : ${e_nf}/${cnt} not found" 2806 2807 status ${ret} 2808} 2809 2810function luks_test() 2811{ 2812 hashType=$1 2813 attackType=$2 2814 2815 # if -m all was set let us default to -a 3 only. You could specify the attack type directly, e.g. -m 0 2816 # the problem with defaulting to all=0,1,3,6,7 is that it could take way too long 2817 2818 if [ "${attackType}" -eq 65535 ]; then 2819 attackType=3 2820 fi 2821 2822 #LUKS_HASHES="sha1 sha256 sha512 ripemd160 whirlpool" 2823 LUKS_HASHES="sha1 sha256 sha512 ripemd160" 2824 LUKS_CIPHERS="aes serpent twofish" 2825 LUKS_MODES="cbc-essiv cbc-plain64 xts-plain64" 2826 LUKS_KEYSIZES="128 256 512" 2827 2828 LUKS_PASSWORD=$(cat "${TDIR}/luks_tests/pw") 2829 2830 for luks_h in ${LUKS_HASHES}; do 2831 for luks_c in ${LUKS_CIPHERS}; do 2832 for luks_m in ${LUKS_MODES}; do 2833 for luks_k in ${LUKS_KEYSIZES}; do 2834 2835 CMD="" 2836 2837 # filter out not supported combinations: 2838 2839 case "${luks_k}" in 2840 128) 2841 case "${luks_m}" in 2842 cbc-essiv|cbc-plain64) 2843 ;; 2844 *) 2845 continue 2846 ;; 2847 esac 2848 ;; 2849 256) 2850 case "${luks_m}" in 2851 cbc-essiv|cbc-plain64|xts-plain64) 2852 ;; 2853 *) 2854 continue 2855 ;; 2856 esac 2857 ;; 2858 512) 2859 case "${luks_m}" in 2860 xts-plain64) 2861 ;; 2862 *) 2863 continue 2864 ;; 2865 esac 2866 ;; 2867 esac 2868 2869 luks_mode="${luks_h}-${luks_c}-${luks_m}-${luks_k}" 2870 luks_file="${TDIR}/luks_tests/hashcat_${luks_h}_${luks_c}_${luks_m}_${luks_k}.luks" 2871 luks_main_mask="?l" 2872 luks_mask="${luks_main_mask}" 2873 2874 # for combination or hybrid attacks 2875 luks_pass_part_file1="${OUTD}/${hashType}_dict1" 2876 luks_pass_part_file2="${OUTD}/${hashType}_dict2" 2877 2878 case $attackType in 2879 0) 2880 CMD="./${BIN} ${OPTS} -a 0 -m ${hashType} ${luks_file} ${TDIR}/luks_tests/pw" 2881 ;; 2882 1) 2883 luks_pass_part1_len=$((${#LUKS_PASSWORD} / 2)) 2884 luks_pass_part2_start=$((luks_pass_part1_len + 1)) 2885 2886 echo "${LUKS_PASSWORD}" | cut -c-${luks_pass_part1_len} > "${luks_pass_part_file1}" 2887 echo "${LUKS_PASSWORD}" | cut -c${luks_pass_part2_start}- > "${luks_pass_part_file2}" 2888 2889 CMD="./${BIN} ${OPTS} -a 6 -m ${hashType} ${luks_file} ${luks_pass_part_file1} ${luks_pass_part_file2}" 2890 ;; 2891 3) 2892 luks_mask_fixed_len=$((${#LUKS_PASSWORD} - 1)) 2893 2894 luks_mask="$(echo "${LUKS_PASSWORD}" | cut -c-${luks_mask_fixed_len})" 2895 luks_mask="${luks_mask}${luks_main_mask}" 2896 2897 CMD="./${BIN} ${OPTS} -a 3 -m ${hashType} ${luks_file} ${luks_mask}" 2898 ;; 2899 6) 2900 luks_pass_part1_len=$((${#LUKS_PASSWORD} - 1)) 2901 2902 echo "${LUKS_PASSWORD}" | cut -c-${luks_pass_part1_len} > "${luks_pass_part_file1}" 2903 2904 CMD="./${BIN} ${OPTS} -a 6 -m ${hashType} ${luks_file} ${luks_pass_part_file1} ${luks_mask}" 2905 ;; 2906 7) 2907 echo "${LUKS_PASSWORD}" | cut -c2- > "${luks_pass_part_file1}" 2908 2909 CMD="./${BIN} ${OPTS} -a 7 -m ${hashType} ${luks_file} ${luks_mask} ${luks_pass_part_file1}" 2910 ;; 2911 esac 2912 2913 if [ -n "${CMD}" ]; then 2914 echo "> Testing hash type ${hashType} with attack mode ${attackType}, markov ${MARKOV}, single hash, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}, luksMode ${luks_mode}" >> "${OUTD}/logfull.txt" 2>> "${OUTD}/logfull.txt" 2915 2916 output=$(${CMD} 2>&1) 2917 ret=${?} 2918 2919 echo "${output}" >> "${OUTD}/logfull.txt" 2920 2921 cnt=1 2922 e_nf=0 2923 msg="OK" 2924 2925 if [ ${ret} -ne 0 ]; then 2926 e_nf=1 2927 msg="Error" 2928 fi 2929 2930 echo "[ ${OUTD} ] [ Type ${hash_type}, Attack ${attackType}, Mode single, Device-Type ${TYPE}, Kernel-Type ${KERNEL_TYPE}, Vector-Width ${VECTOR}, luksMode ${luks_mode} ] > $msg : ${e_nf}/${cnt} not found" 2931 2932 status ${ret} 2933 fi 2934 done 2935 done 2936 done 2937 done 2938} 2939 2940function usage() 2941{ 2942cat << EOF 2943> Usage : ${0} <options> 2944 2945OPTIONS: 2946 2947 -V Backend vector-width (either 1, 2, 4 or 8), overrides value from device query : 2948 '1' => vector-width 1 2949 '2' => vector-width 2 (default) 2950 '4' => vector-width 4 2951 '8' => vector-width 8 2952 'all' => test sequentially vector-width ${VECTOR_WIDTHS} 2953 2954 -t Select test mode : 2955 'single' => single hash (default) 2956 'multi' => multi hash 2957 'all' => single and multi hash 2958 2959 -m Select hash type : 2960 'all' => all hash type supported 2961 (int) => hash type integer code (default : 0) 2962 (int)-(int) => hash type integer range 2963 2964 -a Select attack mode : 2965 'all' => all attack modes 2966 (int) => attack mode integer code (default : 0) 2967 2968 -x Select cpu architecture : 2969 '32' => 32 bit architecture 2970 '64' => 64 bit architecture (default) 2971 2972 -o Select operating system : 2973 'win' => Windows operating system (use .exe file extension) 2974 'linux' => Linux operating system (use .bin file extension) 2975 'macos' => macOS operating system (use .app file extension) 2976 2977 -d Select the Backend device : 2978 (int)[,int] => comma separated list of devices (default : 1) 2979 2980 -D Select the OpenCL device types : 2981 '1' => CPU 2982 '2' => GPU (default) 2983 '3' => FPGA, DSP, Co-Processor 2984 (int)[,int] => multiple comma separated device types from the list above 2985 2986 -O Use optimized kernels (default : -O) 2987 2988 -P Use pure kernels instead of optimized kernels (default : -O) 2989 2990 -s Use this session name instead of the default one (default : "hashcat") 2991 2992 -c Disables markov-chains 2993 2994 -p Package the tests into a .7z file 2995 2996 -F Use this folder as test folder instead of the default one 2997 (string) => path to folder 2998 2999 -I Use this folder as input/output folder for packaged tests 3000 (string) => path to folder 3001 3002 -h Show this help 3003 3004EOF 3005 3006 exit 1 3007} 3008 3009BIN="hashcat" 3010MARKOV="enabled" 3011ATTACK=0 3012MODE=0 3013TYPE="null" 3014KERNEL_TYPE="Optimized" 3015VECTOR="default" 3016HT=0 3017PACKAGE=0 3018OPTIMIZED=1 3019 3020while getopts "V:t:m:a:b:hcpd:x:o:d:D:F:POI:s:" opt; do 3021 3022 case ${opt} in 3023 "V") 3024 if [ "${OPTARG}" = "1" ]; then 3025 VECTOR=1 3026 elif [ "${OPTARG}" = "2" ]; then 3027 VECTOR=2 3028 elif [ "${OPTARG}" = "4" ]; then 3029 VECTOR=4 3030 elif [ "${OPTARG}" = "8" ]; then 3031 VECTOR=8 3032 elif [ "${OPTARG}" = "16" ]; then 3033 VECTOR=16 3034 elif [ "${OPTARG}" = "all" ]; then 3035 VECTOR="all" 3036 else 3037 usage 3038 fi 3039 ;; 3040 3041 "t") 3042 if [ "${OPTARG}" = "single" ]; then 3043 MODE=0 3044 elif [ "${OPTARG}" = "multi" ]; then 3045 MODE=1 3046 elif [ "${OPTARG}" = "all" ]; then 3047 MODE=2 3048 else 3049 usage 3050 fi 3051 ;; 3052 3053 "m") 3054 if [ "${OPTARG}" = "all" ]; then 3055 HT=65535 3056 else 3057 HT=${OPTARG} 3058 fi 3059 ;; 3060 3061 "a") 3062 if [ "${OPTARG}" = "all" ]; then 3063 ATTACK=65535 3064 elif [ "${OPTARG}" = "0" ]; then 3065 ATTACK=0 3066 elif [ "${OPTARG}" = "1" ]; then 3067 ATTACK=1 3068 elif [ "${OPTARG}" = "3" ]; then 3069 ATTACK=3 3070 elif [ "${OPTARG}" = "6" ]; then 3071 ATTACK=6 3072 elif [ "${OPTARG}" = "7" ]; then 3073 ATTACK=7 3074 else 3075 usage 3076 fi 3077 ;; 3078 3079 "c") 3080 OPTS="${OPTS} --markov-disable" 3081 MARKOV="disabled" 3082 ;; 3083 3084 "I") 3085 PACKAGE_FOLDER=$( echo "${OPTARG}" | sed 's!/$!!g' ) 3086 ;; 3087 3088 "s") 3089 OPTS="${OPTS} --session \"${OPTARG}\"" 3090 ;; 3091 3092 "p") 3093 PACKAGE=1 3094 ;; 3095 3096 "x") 3097 if [ "${OPTARG}" = "32" ]; then 3098 ARCHITECTURE=32 3099 elif [ "${OPTARG}" = "64" ]; then 3100 ARCHITECTURE=64 3101 else 3102 usage 3103 fi 3104 ;; 3105 3106 "o") 3107 if [ "${OPTARG}" = "win" ]; then 3108 EXTENSION="exe" 3109 elif [ "${OPTARG}" = "linux" ]; then 3110 EXTENSION="bin" 3111 elif [ "${OPTARG}" = "macos" ]; then 3112 EXTENSION="app" 3113 else 3114 usage 3115 fi 3116 ;; 3117 3118 "O") 3119 # optimized is already default, ignore it 3120 ;; 3121 3122 "d") 3123 OPTS="${OPTS} -d ${OPTARG}" 3124 ;; 3125 3126 "D") 3127 if [ "${OPTARG}" = "1" ]; then 3128 OPTS="${OPTS} -D 1" 3129 TYPE="Cpu" 3130 elif [ "${OPTARG}" = "2" ]; then 3131 OPTS="${OPTS} -D 2" 3132 TYPE="Gpu" 3133 else 3134 OPTS="${OPTS} -D ${OPTARG}" 3135 TYPE="Cpu + Gpu" 3136 fi 3137 ;; 3138 3139 "F") 3140 OUTD=$( echo "${OPTARG}" | sed 's!/$!!g' ) 3141 ;; 3142 3143 "P") 3144 OPTIMIZED=0 3145 KERNEL_TYPE="Pure" 3146 ;; 3147 3148 \?) 3149 usage 3150 ;; 3151 3152 "h") 3153 usage 3154 ;; 3155 esac 3156 3157done 3158 3159export IS_OPTIMIZED=${OPTIMIZED} 3160 3161if [ "${OPTIMIZED}" -eq 1 ]; then 3162 OPTS="${OPTS} -O" 3163fi 3164 3165if [ "${TYPE}" = "null" ]; then 3166 OPTS="${OPTS} -D 2" 3167 TYPE="Gpu" 3168fi 3169 3170if [ -n "${ARCHITECTURE}" ]; then 3171 3172 BIN="${BIN}${ARCHITECTURE}" 3173 3174fi 3175 3176if [ -n "${EXTENSION}" ]; then 3177 3178 BIN="${BIN}.${EXTENSION}" 3179 3180fi 3181 3182if [ -n "${PACKAGE_FOLDER}" ]; then 3183 3184 if [ ! -e "${PACKAGE_FOLDER}" ]; then 3185 echo "! folder '${PACKAGE_FOLDER}' does not exist" 3186 exit 1 3187 fi 3188 3189fi 3190 3191if [ "${PACKAGE}" -eq 0 ] || [ -z "${PACKAGE_FOLDER}" ]; then 3192 3193 # check existence of binary 3194 if [ ! -e "${BIN}" ]; then 3195 echo "! ${BIN} not found, please build binary before run test." 3196 exit 1 3197 fi 3198 3199 HT_MIN=0 3200 HT_MAX=0 3201 3202 if echo -n "${HT}" | grep -q '^[0-9]\+$'; then 3203 HT_MIN=${HT} 3204 HT_MAX=${HT} 3205 elif echo -n "${HT}" | grep -q '^[0-9]\+-[1-9][0-9]*$'; then 3206 3207 HT_MIN=$(echo -n ${HT} | sed "s/-.*//") 3208 HT_MAX=$(echo -n ${HT} | sed "s/.*-//") 3209 3210 if [ "${HT_MIN}" -gt "${HT_MAX}" ]; then 3211 echo "! hash type range -m ${HT} is not valid ..." 3212 usage 3213 fi 3214 else 3215 echo "! hash type is not a number ..." 3216 usage 3217 fi 3218 3219 HT=${HT_MIN} 3220 3221 # filter by hash_type 3222 if [ "${HT}" -ne 65535 ]; then 3223 3224 # validate filter 3225 3226 if ! is_in_array "${HT_MIN}" ${HASH_TYPES}; then 3227 echo "! invalid hash type selected ..." 3228 usage 3229 fi 3230 3231 if ! is_in_array "${HT_MAX}" ${HASH_TYPES}; then 3232 echo "! invalid hash type selected ..." 3233 usage 3234 fi 3235 fi 3236 3237 if [ -z "${PACKAGE_FOLDER}" ]; then 3238 3239 # make new dir 3240 mkdir -p "${OUTD}" 3241 3242 # generate random test entry 3243 if [ "${HT}" -eq 65535 ]; then 3244 for TMP_HT in ${HASH_TYPES}; do 3245 if [ "${TMP_HT}" -ne ${LUKS_MODE} ]; then 3246 if ! is_in_array "${TMP_HT}" ${TC_MODES}; then 3247 if ! is_in_array "${TMP_HT}" ${VC_MODES}; then 3248 if ! is_in_array "${TMP_HT}" ${CL_MODES}; then 3249 perl tools/test.pl single "${TMP_HT}" >> "${OUTD}/all.sh" 3250 fi 3251 fi 3252 fi 3253 fi 3254 done 3255 else 3256 for TMP_HT in $(seq "${HT_MIN}" "${HT_MAX}"); do 3257 if ! is_in_array "${TMP_HT}" ${HASH_TYPES}; then 3258 continue 3259 fi 3260 3261 if [ "${TMP_HT}" -ne ${LUKS_MODE} ]; then 3262 # Exclude TrueCrypt and VeraCrypt testing modes 3263 if ! is_in_array "${TMP_HT}" ${TC_MODES}; then 3264 if ! is_in_array "${TMP_HT}" ${VC_MODES}; then 3265 if ! is_in_array "${TMP_HT}" ${CL_MODES}; then 3266 perl tools/test.pl single "${TMP_HT}" >> "${OUTD}/all.sh" 3267 fi 3268 fi 3269 fi 3270 fi 3271 done 3272 fi 3273 3274 else 3275 3276 OUTD=${PACKAGE_FOLDER} 3277 3278 fi 3279 3280 rm -rf "${OUTD}/logfull.txt" && touch "${OUTD}/logfull.txt" 3281 3282 # populate array of hash types where we only should check if pass is in output (not both hash:pass) 3283 IFS=';' read -ra PASS_ONLY <<< "${HASHFILE_ONLY} ${NOCHECK_ENCODING}" 3284 IFS=';' read -ra TIMEOUT_ALGOS <<< "${SLOW_ALGOS}" 3285 3286 IFS=';' read -ra NEVER_CRACK_ALGOS <<< "${NEVER_CRACK}" 3287 3288 # for these particular algos we need to save the output to a temporary file 3289 IFS=';' read -ra FILE_BASED_ALGOS <<< "${HASHFILE_ONLY}" 3290 3291 for hash_type in $HASH_TYPES; do 3292 3293 if [ "${HT}" -ne 65535 ]; then 3294 3295 # check if the loop variable "hash_type" is between HT_MIN and HT_MAX (both included) 3296 3297 if [ "${hash_type}" -lt "${HT_MIN}" ]; then 3298 continue 3299 elif [ "${hash_type}" -gt "${HT_MAX}" ]; then 3300 # we are done because hash_type is larger than range: 3301 break 3302 fi 3303 fi 3304 3305 if [ "${hash_type}" -eq 20510 ]; then # special case for PKZIP Master Key 3306 if [ "${MODE}" -eq 1 ]; then # if "multi" was forced we need to skip it 3307 if [ "${HT_MIN}" -eq 20510 ]; then 3308 if [ "${HT_MAX}" -eq 20510 ]; then 3309 echo "ERROR: -m 20510 = PKZIP Master Key can only be run with a single hash" 3310 fi 3311 fi 3312 3313 continue 3314 fi 3315 fi 3316 3317 if [ -z "${PACKAGE_FOLDER}" ]; then 3318 3319 # init test data 3320 init 3321 3322 else 3323 3324 echo "[ ${OUTD} ] > Run packaged test for hash type $hash_type." 3325 3326 fi 3327 3328 if [ "${PACKAGE}" -eq 0 ]; then 3329 3330 # should we check only the pass? 3331 pass_only=0 3332 is_in_array "${hash_type}" ${PASS_ONLY} && pass_only=1 3333 3334 IS_SLOW=0 3335 is_in_array "${hash_type}" ${SLOW_ALGOS} && IS_SLOW=1 3336 3337 # we use phpass as slow hash for testing the AMP kernel 3338 [ "${hash_type}" -eq 400 ] && IS_SLOW=0 3339 3340 OPTS_OLD=${OPTS} 3341 VECTOR_OLD=${VECTOR} 3342 MODE_OLD=${MODE} 3343 3344 if [ "${hash_type}" -eq 20510 ]; then # special case for PKZIP Master Key 3345 if [ "${MODE}" -eq 1 ]; then # if "multi" was forced we need to skip it 3346 continue 3347 fi 3348 3349 MODE=0 # force single only 3350 fi 3351 3352 for CUR_WIDTH in $VECTOR_WIDTHS; do 3353 3354 if [ "${VECTOR_OLD}" = "all" ] || [ "${VECTOR_OLD}" = "default" ] || [ "${VECTOR_OLD}" = "${CUR_WIDTH}" ]; then 3355 3356 if [ "${VECTOR_OLD}" = "default" ] && \ 3357 [ "${CUR_WIDTH}" != "1" ] && \ 3358 [ "${CUR_WIDTH}" != "4" ]; then 3359 3360 continue 3361 fi 3362 3363 VECTOR=${CUR_WIDTH} 3364 OPTS="${OPTS_OLD} --backend-vector-width ${VECTOR}" 3365 3366 if [ ${IS_SLOW} -eq 1 ]; then 3367 3368 # Look up if this is one of supported VeraCrypt modes 3369 if is_in_array "${hash_type}" ${VC_MODES}; then 3370 veracrypt_test 0 # aes 3371 veracrypt_test 1 # serpent 3372 veracrypt_test 2 # twofish 3373 veracrypt_test 3 # camellia 3374 veracrypt_test 4 # camellia (alternative cascade) 3375 veracrypt_test 5 # kuznyechik 3376 veracrypt_test 6 # kuznyechik (alternative cascade) 3377 elif is_in_array "${hash_type}" ${TC_MODES}; then 3378 # run truecrypt tests 3379 truecrypt_test "${hash_type}" 0 3380 truecrypt_test "${hash_type}" 1 3381 truecrypt_test "${hash_type}" 2 3382 elif [ "${hash_type}" -eq ${LUKS_MODE} ]; then 3383 # run luks tests 3384 luks_test "${hash_type}" ${ATTACK} 3385 else 3386 # run attack mode 0 (stdin) 3387 if [ ${ATTACK} -eq 65535 ] || [ ${ATTACK} -eq 0 ]; then attack_0; fi 3388 fi 3389 3390 else 3391 3392 if is_in_array "${hash_type}" ${CL_MODES}; then 3393 # run cryptoloop tests 3394 cryptoloop_test "${hash_type}" 128 3395 cryptoloop_test "${hash_type}" 192 3396 cryptoloop_test "${hash_type}" 256 3397 else 3398 # run attack mode 0 (stdin) 3399 if [ ${ATTACK} -eq 65535 ] || [ ${ATTACK} -eq 0 ]; then attack_0; fi 3400 3401 # run attack mode 1 (combinator) 3402 if [ ${ATTACK} -eq 65535 ] || [ ${ATTACK} -eq 1 ]; then attack_1; fi 3403 3404 # run attack mode 3 (bruteforce) 3405 if [ ${ATTACK} -eq 65535 ] || [ ${ATTACK} -eq 3 ]; then attack_3; fi 3406 3407 # run attack mode 6 (dict+mask) 3408 if [ ${ATTACK} -eq 65535 ] || [ ${ATTACK} -eq 6 ]; then attack_6; fi 3409 3410 # run attack mode 7 (mask+dict) 3411 if [ ${ATTACK} -eq 65535 ] || [ ${ATTACK} -eq 7 ]; then attack_7; fi 3412 fi 3413 3414 fi 3415 fi 3416 done 3417 OPTS="${OPTS_OLD}" 3418 VECTOR="${VECTOR_OLD}" 3419 MODE=${MODE_OLD} 3420 fi 3421 done 3422 3423else 3424 3425 OUTD=${PACKAGE_FOLDER} 3426 3427fi 3428 3429# fix logfile 3430if [ "${PACKAGE}" -eq 0 ]; then 3431 cat -vet "${OUTD}/logfull.txt" | sed -e 's/\^M \^M//g' | sed -e 's/\$$//g' > "${OUTD}/test_report.log" 3432fi 3433 3434rm -rf "${OUTD}/logfull.txt" 3435 3436if [ "${PACKAGE}" -eq 1 ]; then 3437 3438 echo "[ ${OUTD} ] > Generate package ${OUTD}/${OUTD}.7z" 3439 3440 cp "${BASH_SOURCE[0]}" "${OUTD}/test.sh" 3441 3442 copy_luks_dir=0 3443 copy_tc_dir=0 3444 copy_vc_dir=0 3445 copy_cl_dir=0 3446 3447 if [ "${HT}" -eq 65535 ]; then 3448 copy_luks_dir=1 3449 copy_tc_dir=1 3450 copy_vc_dir=1 3451 copy_cl_dir=1 3452 else 3453 for TMP_HT in $(seq "${HT_MIN}" "${HT_MAX}"); do 3454 if [ "${TMP_HT}" -eq "${LUKS_MODE}" ]; then 3455 copy_luks_dir=1 3456 elif is_in_array "${TMP_HT}" ${TC_MODES}; then 3457 copy_tc_dir=1 3458 elif is_in_array "${TMP_HT}" ${VC_MODES}; then 3459 copy_vc_dir=1 3460 elif is_in_array "${TMP_HT}" ${CL_MODES}; then 3461 copy_cl_dir=1 3462 fi 3463 done 3464 fi 3465 3466 if [ "${copy_luks_dir}" -eq 1 ]; then 3467 mkdir "${OUTD}/luks_tests/" 3468 cp ${TDIR}/luks_tests/* "${OUTD}/luks_tests/" 3469 fi 3470 3471 if [ "${copy_tc_dir}" -eq 1 ]; then 3472 mkdir "${OUTD}/tc_tests/" 3473 cp ${TDIR}/tc_tests/* "${OUTD}/tc_tests/" 3474 fi 3475 3476 if [ "${copy_vc_dir}" -eq 1 ]; then 3477 mkdir "${OUTD}/vc_tests/" 3478 cp ${TDIR}/vc_tests/* "${OUTD}/vc_tests/" 3479 fi 3480 3481 if [ "${copy_cl_dir}" -eq 1 ]; then 3482 mkdir "${OUTD}/cl_tests/" 3483 cp ${TDIR}/cl_tests/* "${OUTD}/cl_tests/" 3484 fi 3485 3486 # if we package from a given folder, we need to check if e.g. the files needed for multi mode are there 3487 3488 if [ -n "${PACKAGE_FOLDER}" ]; then 3489 3490 MODE=2 3491 3492 ls "${PACKAGE_FOLDER}"/*multi* >/dev/null 2>/dev/null 3493 3494 if [ "${?}" -ne 0 ] 3495 then 3496 3497 MODE=0 3498 3499 fi 3500 3501 HT=$(grep -o -- "-m *[0-9]*" "${PACKAGE_FOLDER}/all.sh" | sort -u | sed 's/-m //' 2> /dev/null) 3502 3503 if [ -n "${HT}" ]; then 3504 3505 HT_COUNT=$(echo "${HT}" | wc -l) 3506 3507 if [ "${HT_COUNT}" -gt 1 ]; then 3508 3509 HT=65535 3510 3511 fi 3512 3513 fi 3514 3515 #ATTACK=65535 # more appropriate ? 3516 fi 3517 3518 # for convenience: 'run package' is default action for packaged test.sh ( + add other defaults too ) 3519 3520 SED_IN_PLACE='-i' 3521 3522 UNAME=$(uname -s) 3523 3524 # of course macOS requires us to implement a special case (sed -i "" for the backup file) 3525 if [ "${UNAME}" = "Darwin" ] ; then 3526 SED_IN_PLACE='-i ""' 3527 fi 3528 3529 HT_PACKAGED=${HT} 3530 3531 if [ "${HT_MIN}" -ne "${HT_MAX}" ]; then 3532 HT_PACKAGED=${HT_MIN}-${HT_MAX} 3533 fi 3534 3535 HASH_TYPES_PACKAGED=$( echo "${HASH_TYPES}" | tr '\n' ' ' | sed 's/ $//') 3536 HASHFILE_ONLY_PACKAGED=$(echo "${HASHFILE_ONLY}" | tr '\n' ' ' | sed 's/ $//') 3537 NEVER_CRACK_PACKAGED=$( echo "${NEVER_CRACK}" | tr '\n' ' ' | sed 's/ $//') 3538 SLOW_ALGOS_PACKAGED=$( echo "${SLOW_ALGOS}" | tr '\n' ' ' | sed 's/ $//') 3539 3540 sed "${SED_IN_PLACE}" -e 's/^\(PACKAGE_FOLDER\)=""/\1="$( echo "${BASH_SOURCE[0]}" | sed \"s!test.sh\\$!!\" )"/' \ 3541 -e "s/^\(HASH_TYPES\)=\$(.*/\1=\"${HASH_TYPES_PACKAGED}\"/" \ 3542 -e "s/^\(HASHFILE_ONLY\)=\$(.*/\1=\"${HASHFILE_ONLY_PACKAGED}\"/" \ 3543 -e "s/^\(NEVER_CRACK\)=\$(.*/\1=\"${NEVER_CRACK_PACKAGED}\"/" \ 3544 -e "s/^\(SLOW_ALGOS\)=\$(.*/\1=\"${SLOW_ALGOS_PACKAGED}\"/" \ 3545 -e "s/^\(HT\)=0/\1=${HT_PACKAGED}/" \ 3546 -e "s/^\(MODE\)=0/\1=${MODE}/" \ 3547 -e "s/^\(ATTACK\)=0/\1=${ATTACK}/" \ 3548 "${OUTD}/test.sh" 3549 3550 ${PACKAGE_CMD} "${OUTD}/${OUTD}.7z" "${OUTD}/" >/dev/null 2>/dev/null 3551 3552fi 3553