shadow

package
v0.795.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 1, 2026 License: AGPL-3.0 Imports: 3 Imported by: 0

Documentation

Overview

Package shadow decodes a Linux /etc/shadow file for credential triage.

/etc/shadow is the single highest-value Linux post-exploitation artifact: it holds every local account's password hash. This parses a looted shadow file offline and, per user, classifies the password field — the hashing scheme (sha512crypt / sha256crypt / md5crypt / bcrypt / yescrypt / descrypt / …), the matching crack mode (hashcat mode + john format), and the account status (active / locked / no-password / disabled). It surfaces the two findings that matter most: accounts with a crackable hash (with the exact mode to feed the cracker) and accounts with NO password at all.

No confidently-wrong output: the password field is classified only by its documented crypt id ($6$, $2y$, …) or shape (13-char descrypt, status markers * / ! / empty); an unrecognised field is reported scheme "unknown" with no crack mode, never guessed; a hashcat mode is emitted only for schemes hashcat supports natively (yescrypt/gost-yescrypt are reported john-only). A locked account whose hash is still present ("!$6$…") is flagged locked *and* crackable — the lock only disables login, the hash is still recoverable. Input with no shadow-shaped line is rejected; a passwd-style "x" placeholder is reported as shadowed, not a hash.

Wrap-vs-native: native — a field split over the documented shadow(5) format and crypt(5) id prefixes; stdlib only, no new go.mod dependency. Crack modes per the hashcat and John the Ripper format tables.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Entry

type Entry struct {
	User string `json:"user"`
	// Status is "active", "locked", "no-password", "disabled", or "shadowed".
	Status string `json:"status"`
	Locked bool   `json:"locked,omitempty"`
	// HashScheme names the crypt scheme when a hash is present.
	HashScheme string `json:"hash_scheme,omitempty"`
	// HashcatMode is the hashcat -m mode, 0 when none/unknown or hashcat lacks a
	// native mode for the scheme (see JohnFormat / Note).
	HashcatMode int    `json:"hashcat_mode,omitempty"`
	JohnFormat  string `json:"john_format,omitempty"`
	// Crackable is true when a real password hash is present (regardless of lock).
	Crackable bool `json:"crackable"`

	LastChangeDays int    `json:"last_change_days,omitempty"`
	MaxAgeDays     int    `json:"max_age_days,omitempty"`
	ExpireDays     int    `json:"expire_days,omitempty"`
	Note           string `json:"note,omitempty"`
}

Entry is one decoded shadow line.

type Result

type Result struct {
	Format          string  `json:"format"`
	Entries         []Entry `json:"entries"`
	CrackableCount  int     `json:"crackable_count"`
	NoPasswordCount int     `json:"no_password_count"`
	LockedCount     int     `json:"locked_count"`
	Note            string  `json:"note"`
}

Result is the decoded shadow file.

func Decode

func Decode(input string) (*Result, error)

Decode parses an /etc/shadow file.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL