Very early test stage of scripts to extract ntlm and kerberos hashes from pcaps.

3 min read Original article ↗

Very early test stage of scripts to extract ntlm and kerberos hashes from pcaps.

#!/bin/bash
if [ -z "$1" ]
then
echo "Usage: $0 <pcapfile>"
exit 1
fi
PCAP="$1"
# Handle AS-REP and TGS-REP (using tshark)
tshark -r "$PCAP" -Y "kerberos.msg_type == 11 || kerberos.msg_type == 13" -T fields \
-e frame.number \
-e kerberos.msg_type \
-e kerberos.realm \
-e kerberos.CNameString \
-e kerberos.etype \
-e kerberos.cipher | while IFS=$'\t' read -r frame msg_type crealm cname etype cipher; do
[[ -z "$msg_type" || -z "$crealm" || -z "$cname" || -z "$etype" || -z "$cipher" ]] && continue
realm_upper=$(echo "$crealm" | tr '[:lower:]' '[:upper:]')
cname_clean=$(echo "$cname" | tr -d ' ,\r\n')
etype_clean=$(echo "$etype" | cut -d',' -f1)
cipher_clean=$(echo "$cipher" | tr -d ' ,\r\n')
case "$msg_type" in
11)
checksum="${cipher_clean:0:32}"
encrypted_data="${cipher_clean:32}"
echo "\$krb5asrep\$${etype_clean}\$${cname_clean}@${realm_upper}:${checksum}\$${encrypted_data}"
;;
13)
service="krbtgt/${realm_upper}*"
checksum="${cipher_clean:0:32}"
encrypted_ticket="${cipher_clean:32}"
echo "\$krb5tgs\$${etype_clean}\$*${cname_clean}\$${realm_upper}\$${service}\$${checksum}\$${encrypted_ticket}"
;;
esac
done
# Handle AS-REQ (msg_type 10, using padata_value instead of cipher)
tshark -r "$PCAP" -Y "kerberos.msg_type == 10" -T fields \
-e frame.number \
-e kerberos.msg_type \
-e kerberos.realm \
-e kerberos.etype \
-e kerberos.padata_value | while IFS=$'\t' read -r frame msg_type crealm etype padata; do
[[ -z "$msg_type" || -z "$crealm" || -z "$etype" || -z "$padata" ]] && continue
etype_name() {
case "$1" in
1) echo "des-cbc-crc" ;;
3) echo "des-cbc-md5" ;;
16) echo "des3" ;;
17) echo "aes128" ;;
18) echo "aes256" ;;
23) echo "u5" ;; # RC4-HMAC
*) echo "etype$1" ;; # fallback, unknown etype
esac
}
realm_upper=$(echo "$crealm" | tr '[:lower:]' '[:upper:]')
etype_clean=$(echo "$etype" | cut -d',' -f1 | tr -d '[:space:]')
padata_clean=$(echo "$padata" | cut -d',' -f1 | tr -d '[:space:]')
encryption_name=$(etype_name $etype_clean)
final_hash=$(python3 ./extract-padata.py "$padata_clean")
if [[ -n "$final_hash" ]]
then
echo "\$krb5pa\$${etype_clean}\$${encryption_name}\$${realm_upper}\$"dummy"\$${final_hash}" >> test-kerberos-hash.txt
fi
done
#!/bin/bash
# Extract valid NTLMv1/v2 hashes from pcap using tshark
# Usage: ./extract_ntlm_hashes.sh file.pcap
pcap_file="$1"
if [[ -z "$pcap_file" ]]; then
echo "Usage: $0 <file.pcap>"
exit 1
fi
echo "[*] Extracting NTLMv2/v1 hashes from $pcap_file..."
# Step 1: Get Challenge messages (Type 2)
declare -A challenges
while IFS=$'\t' read -r stream_id challenge; do
if [[ "$challenge" =~ ^[a-fA-F0-9]{16}$ ]]; then
challenges["$stream_id"]="$challenge"
fi
done < <(tshark -r "$pcap_file" \
-Y "ntlmssp.ntlmserverchallenge" \
-T fields \
-e tcp.stream \
-e ntlmssp.ntlmserverchallenge)
# Step 2: Get Auth messages (Type 3)
tshark -r "$pcap_file" \
-Y "ntlmssp.auth.username and ntlmssp.auth.ntresponse and ntlmssp.auth.lmresponse" \
-T fields \
-e tcp.stream \
-e ntlmssp.auth.username \
-e ntlmssp.auth.domain \
-e ntlmssp.auth.ntresponse \
-e ntlmssp.auth.lmresponse |
while IFS=$'\t' read -r stream_id username domain nt_response lm_response; do
challenge="${challenges[$stream_id]}"
if [[ -z "$challenge" || -z "$username" || -z "$domain" ]]; then
continue
fi
if [[ ! "$nt_response" =~ ^[a-fA-F0-9]+$ || ! "$lm_response" =~ ^[a-fA-F0-9]+$ ]]; then
continue
fi
if [[ ${#nt_response} -gt 48 ]]; then
version="NTLMv2"
nt_proof="${nt_response:0:32}"
blob="${nt_response:32}"
hash="$username::$domain:$challenge:$nt_proof:$blob"
elif [[ ${#nt_response} -eq 48 ]]; then
version="NTLMv1"
hash="$username::$domain:$lm_response:$nt_response:$challenge"
else
continue
fi
echo "[$version] $hash"
echo "$hash" >> pcap-hashes.txt
done
import sys
from impacket.krb5.asn1 import EncryptedData
from pyasn1.codec.der.decoder import decode as der_decode
def main():
if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} <padata_value_hex>")
sys.exit(1)
padata_hex = sys.argv[1]
try:
padata_bytes = bytes.fromhex(padata_hex)
enc_data, _ = der_decode(padata_bytes, asn1Spec=EncryptedData())
cipher = bytes(enc_data['cipher']).hex()
checksum = cipher[:32]
encrypted_data = cipher[32:]
final_hash = encrypted_data + checksum
print(final_hash)
except Exception as e:
#print(f"Error decoding padata_value: {e}", file=sys.stderr)
sys.exit(2)
if __name__ == "__main__":
main()