-
-
Notifications
You must be signed in to change notification settings - Fork 244
/
Copy pathS109_jtr_local_pw_cracking.sh
executable file
·192 lines (167 loc) · 7.45 KB
/
S109_jtr_local_pw_cracking.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#!/bin/bash -p
# EMBA - EMBEDDED LINUX ANALYZER
#
# Copyright 2020-2025 Siemens Energy AG
#
# EMBA comes with ABSOLUTELY NO WARRANTY. This is free software, and you are
# welcome to redistribute it under the terms of the GNU General Public License.
# See LICENSE file for usage of this software.
#
# EMBA is licensed under GPLv3
# SPDX-License-Identifier: GPL-3.0-only
#
# Author(s): Michael Messner
# Description: Cracks password hashes from S109 (STACS module) with jtr
# jtr runtime is 60 minutes
S109_jtr_local_pw_cracking() {
module_log_init "${FUNCNAME[0]}"
if [[ "${QUICK_SCAN:-0}" -eq 1 ]]; then
module_end_log "${FUNCNAME[0]}" 0
return
fi
local lPW_FILE="${CSV_DIR}"/s108_stacs_password_search.csv
local lPW_FILE_S107="${CSV_DIR}"/s107_deep_password_search.csv
local lNEG_LOG=0
local lHASHES_S107_ARR=()
local lHASHES_S108_ARR=()
local lHASHES_ARR=()
local lHASH=""
local lHASH_SOURCE=""
local lCRACKED_HASHES_ARR=()
local lJTR_FINAL_STAT=""
local lCRACKED_HASH=""
local lCRACKED=0
local lJTR_TIMEOUT="3600"
# optional wordlist for JTR - if no wordlist is there JTR runs in default mode
local lJTR_WORDLIST="${CONFIG_DIR}/jtr_wordlist.txt"
local lHASH_DESCRIPTION=""
local lJTR_FORMATS_ARR=()
local lJTR_FORMAT=""
local lPID=""
# This module waits for S108_stacs_password_search and S107_deep_password_search
# check emba.log for S108_stacs_password_search starting
module_wait "S107_deep_password_search"
module_wait "S108_stacs_password_search"
module_title "Cracking identified password hashes"
pre_module_reporter "${FUNCNAME[0]}"
if [[ -f "${lPW_FILE_S107}" ]]; then
mapfile -t lHASHES_S107_ARR < <(cut -d\; -f1,2,3 "${lPW_FILE_S107}" | grep -v "PW_HASH" | sort -k 2 -t \; -u)
fi
if [[ -f "${lPW_FILE}" ]]; then
mapfile -t lHASHES_S108_ARR < <(cut -d\; -f1,2,3 "${lPW_FILE}" | grep -v "PW_PATH;PW_HASH" | sort -k 2 -t \; -u)
lHASHES_ARR=("${lHASHES_S107_ARR[@]}" "${lHASHES_S108_ARR[@]}")
for lHASH in "${lHASHES_ARR[@]}"; do
lHASH_DESCRIPTION=$(basename "$(echo "${lHASH}" | cut -d\; -f1)")
lHASH_SOURCE=$(basename "$(echo "${lHASH}" | cut -d\; -f2)")
lHASH=$(echo "${lHASH}" | cut -d\; -f3 | tr -d \")
[[ "${lHASH}" == *"BEGIN"*"KEY"* ]] && continue
[[ "${lHASH_DESCRIPTION}" == *"private key found"* ]] && continue
if echo "${lHASH}" | cut -d: -f1-3 | grep -q "::[0-9]"; then
# nosemgrep
# removing entries: root::0:0:99999:7:::
continue
fi
if [[ "${lHASH}" == "\$"*"\$"* ]]; then
print_output "[*] Found password data ${ORANGE}${lHASH}${NC} for further processing in ${ORANGE}${lHASH_SOURCE}${NC}"
# put ontop if linux-hash
if [[ ! -s "${LOG_PATH_MODULE}"/jtr_hashes.txt ]]; then
echo "${lHASH}" > "${LOG_PATH_MODULE}"/jtr_hashes.txt
else
sed -i "1s#^#${lHASH}\n#" "${LOG_PATH_MODULE}"/jtr_hashes.txt
fi
else
print_output "[*] Found password data ${ORANGE}${lHASH}${NC} for further processing in ${ORANGE}${lHASH_SOURCE}${NC}"
echo "${lHASH}" >> "${LOG_PATH_MODULE}"/jtr_hashes.txt
fi
done
# sort and make unique
if [[ -f "${LOG_PATH_MODULE}"/jtr_hashes.txt ]]; then
sort -u --o "${LOG_PATH_MODULE}"/jtr_hashes.txt "${LOG_PATH_MODULE}"/jtr_hashes.txt
fi
if [[ -f "${LOG_PATH_MODULE}"/jtr_hashes.txt ]]; then
print_output "[*] Starting jtr with a runtime of ${ORANGE}${lJTR_TIMEOUT}${NC} on the following data:"
tee -a "${LOG_FILE}" < "${LOG_PATH_MODULE}"/jtr_hashes.txt
print_ln
if [[ -f "${lJTR_WORDLIST}" ]]; then
print_output "[*] Starting jtr with the following wordlist: ${ORANGE}${lJTR_WORDLIST}${NC} with ${ORANGE}$(wc -l "${lJTR_WORDLIST}" | awk '{print $1}')${NC} entries."
john --progress-every=120 --wordlist="${lJTR_WORDLIST}" "${LOG_PATH_MODULE}"/jtr_hashes.txt |& safe_logging "${LOG_FILE}" 0 || true &
lPID="$!"
else
john --progress-every=120 "${LOG_PATH_MODULE}"/jtr_hashes.txt |& safe_logging "${LOG_FILE}" 0 || true &
lPID="$!"
fi
sleep 5
local lCOUNT=0
while [[ "${lCOUNT}" -le "${lJTR_TIMEOUT}" ]];do
((lCOUNT+=1))
if ! pgrep john > /dev/null; then
# if no john process is running it means we are finished with cracking passwords
# and we can exit the while loop for waiting
break
fi
sleep 1
done
kill "${lPID}" || true
if pgrep john > /dev/null; then
pkill -f "john" > /dev/null
fi
# lets check our log if we can find further hashes
mapfile -t lJTR_FORMATS_ARR < <(grep "option to force loading hashes of that type instead" "${LOG_FILE}" || true)
# if we have further hashes we are processing these now
if [[ "${#lJTR_FORMATS_ARR[@]}" -gt 0 ]] && [[ "${lCOUNT}" -lt "${lJTR_TIMEOUT}" ]] ; then
print_ln
print_output "[*] Further password hashes detected:"
for lJTR_FORMAT in "${lJTR_FORMATS_ARR[@]}"; do
lJTR_FORMAT="$(echo "${lJTR_FORMAT}" | cut -d '=' -f2 | awk '{print $1}' | tr -d '"' )"
print_output "$(indent "$(orange "Detected hash type: ${lJTR_FORMAT}")")"
done
for lJTR_FORMAT in "${lJTR_FORMATS_ARR[@]}"; do
print_ln
lJTR_FORMAT="$(echo "${lJTR_FORMAT}" | cut -d '=' -f2 | awk '{print $1}' | tr -d '"' )"
print_output "[*] Testing password hash types ${ORANGE}${lJTR_FORMAT}${NC}"
if [[ -f "${lJTR_WORDLIST}" ]]; then
print_output "[*] Starting jtr with the following wordlist: ${ORANGE}${lJTR_WORDLIST}${NC} with ${ORANGE}$(wc -l "${lJTR_WORDLIST}" | awk '{print $1}')${NC} entries."
find "${lJTR_WORDLIST}" | tee -a "${LOG_FILE}"
john --format="${lJTR_FORMAT}" --progress-every=120 --wordlist="${lJTR_WORDLIST}" "${LOG_PATH_MODULE}"/jtr_hashes.txt 2>&1 | tee -a "${LOG_FILE}" || true &
lPID="$!"
else
john --format="${lJTR_FORMAT}" --progress-every=120 "${LOG_PATH_MODULE}"/jtr_hashes.txt 2>&1 | tee -a "${LOG_FILE}" || true &
lPID="$!"
fi
sleep 5
while [[ "${lCOUNT}" -le "${lJTR_TIMEOUT}" ]];do
((lCOUNT+=1))
if ! pgrep john > /dev/null; then
# if no john process is running it means we are finished with cracking passwords
# and we can exit the while loop for waiting
break
fi
sleep 1
done
kill "${lPID}" || true
if pgrep john > /dev/null; then
pkill -f "john" > /dev/null
fi
done
fi
print_ln
lNEG_LOG=1
mapfile -t lCRACKED_HASHES_ARR < <(john --show "${LOG_PATH_MODULE}"/jtr_hashes.txt | grep -v "password hash\(es\)\? cracked" | grep -v "^$" || true)
lJTR_FINAL_STAT=$(john --show "${LOG_PATH_MODULE}"/jtr_hashes.txt | grep "password hash\(es\)\? cracked\|No password hashes loaded" || true)
lCRACKED=$(echo "${lJTR_FINAL_STAT}" | awk '{print $1}')
if [[ -n "${lJTR_FINAL_STAT}" ]]; then
print_ln
print_output "[*] John the ripper final status: ${ORANGE}${lJTR_FINAL_STAT}${NC}"
lNEG_LOG=1
fi
fi
if [[ "${lCRACKED}" -gt 0 ]]; then
for lCRACKED_HASH in "${lCRACKED_HASHES_ARR[@]}"; do
print_output "[+] Password hash cracked: ${ORANGE}${lCRACKED_HASH}${NC}"
lNEG_LOG=1
done
fi
fi
write_log "[*] Statistics:${lCRACKED}"
module_end_log "${FUNCNAME[0]}" "${lNEG_LOG}"
}