Documentation
¶
Index ¶
- Constants
- func ChallengeToken(ntlmMsg []byte) []byte
- func DeriveNTLMv1SigningKey(password string, captured *CapturedHash) ([]byte, error)
- func DeriveNTLMv2SigningKey(password, username, effectiveDomain string, ...) ([]byte, error)
- func ExtractNTLM(blob []byte) []byte
- func FinalToken() []byte
- func InitialSPNEGO() []byte
- func NTLMv1Verify(captured *CapturedHash, password string) bool
- func NTLMv2Verify(captured *CapturedHash, password string) bool
- func NegTokenRespSelectNTLM() []byte
- func SignSMB2Response(signingKey, message []byte)
- func TryCrackDefault(captured *CapturedHash) (string, bool)
- func TryCrackFile(captured *CapturedHash, wordlistPath string) (string, bool)
- type CapturedHash
- type NTLMChallenge
- type NTLMDowngradeLevel
- type NTLMProtocol
- type SMBServer
Constants ¶
const ( NTLMSSP_NEGOTIATE uint32 = 0x00000001 NTLMSSP_CHALLENGE uint32 = 0x00000002 NTLMSSP_AUTH uint32 = 0x00000003 )
── NTLM message types ─────────────────────────────────────────────────────
const ( NTLM_FLAG_UNICODE = 0x00000001 NTLM_FLAG_REQUEST_TARGET = 0x00000004 NTLM_FLAG_NTLM = 0x00000200 NTLM_FLAG_EXTENDED_SESSION_SEC = 0x00080000 NTLM_FLAG_TARGET_INFO = 0x00800000 NTLM_FLAG_128 = 0x20000000 NTLM_FLAG_KEY_EXCH = 0x40000000 NTLM_FLAG_56 = 0x80000000 )
── NTLM negotiate flags ───────────────────────────────────────────────────
const ( MsvAvEOL = uint16(0x0000) MsvAvNbComputerName = uint16(0x0001) MsvAvNbDomainName = uint16(0x0002) MsvAvDnsComputerName = uint16(0x0003) MsvAvDnsDomainName = uint16(0x0004) MsvAvTimestamp = uint16(0x0007) )
── AV Pair IDs ────────────────────────────────────────────────────────────
const ( SMB2_NEGOTIATE uint16 = 0x0000 SMB2_SESSION_SETUP uint16 = 0x0001 SMB2_LOGOFF uint16 = 0x0002 SMB2_TREE_CONNECT uint16 = 0x0003 SMB2_TREE_DISCONNECT uint16 = 0x0004 SMB2_CREATE uint16 = 0x0005 SMB2_CLOSE uint16 = 0x0006 SMB2_FLUSH uint16 = 0x0007 SMB2_READ uint16 = 0x0008 SMB2_WRITE uint16 = 0x0009 SMB2_IOCTL uint16 = 0x000B SMB2_CANCEL uint16 = 0x000C SMB2_ECHO uint16 = 0x000D SMB2_QUERY_DIRECTORY uint16 = 0x000E SMB2_CHANGE_NOTIFY uint16 = 0x000F SMB2_QUERY_INFO uint16 = 0x0010 SMB2_SET_INFO uint16 = 0x0011 )
── SMB2 Commands ──────────────────────────────────────────────────────────
const ( DELETE = 0x00010000 FILE_READ_DATA = 0x00000001 FILE_READ_EA = 0x00000008 FILE_READ_ATTRIBUTES = 0x00000080 )
-- SMB2 access mask flags
const ( STATUS_SUCCESS uint32 = 0x00000000 STATUS_MORE_PROCESSING uint32 = 0xC0000016 STATUS_NOT_IMPLEMENTED uint32 = 0xC0000002 STATUS_INVALID_PARAMETER uint32 = 0xC000000D STATUS_ACCESS_DENIED uint32 = 0xC0000022 STATUS_NO_SUCH_FILE uint32 = 0xC000000F STATUS_OBJECT_NAME_NOT_FOUND uint32 = 0xC0000034 STATUS_OBJECT_NAME_COLLISION uint32 = 0xC0000035 STATUS_END_OF_FILE uint32 = 0xC0000011 STATUS_BAD_NETWORK_NAME uint32 = 0xC00000CC STATUS_LOGON_FAILURE uint32 = 0xC000006D STATUS_NOT_SUPPORTED uint32 = 0xC00000BB STATUS_OBJECT_PATH_NOT_FOUND uint32 = 0xC000003A STATUS_DIRECTORY_NOT_EMPTY uint32 = 0xC0000101 STATUS_FILE_IS_A_DIRECTORY uint32 = 0xC00000BA STATUS_NOT_A_DIRECTORY uint32 = 0xC0000103 STATUS_SHARING_VIOLATION uint32 = 0xC0000043 STATUS_NETWORK_NAME_DELETED uint32 = 0xC00000C9 STATUS_INSUFFICIENT_RESOURCES uint32 = 0xC000009A STATUS_DELETE_PENDING uint32 = 0xC0000056 STATUS_STOPPED_ON_SYMLINK uint32 = 0x8000002D STATUS_IO_REPARSE_TAG_NOT_HANDLED uint32 = 0xC0000279 STATUS_NO_MORE_FILES uint32 = 0x80000006 STATUS_FS_DRIVER_REQUIRED uint32 = 0xC000019C STATUS_NOTIFY_ENUM_DIR uint32 = 0x0000010C STATUS_CANCELLED uint32 = 0xC0000120 )
── NTSTATUS codes ─────────────────────────────────────────────────────────
const ( // SMB2_SESSION_FLAG_IS_GUEST: client MUST set Session.SigningRequired = FALSE. SMB2_SESSION_FLAG_IS_GUEST uint16 = 0x0001 // SMB2_SESSION_FLAG_IS_NULL: null/anonymous session — no credentials were // exchanged and no signing key exists. Per MS-SMB2 §3.2.5.3.1 the client // MUST set Session.SigningRequired = FALSE. Unlike IS_GUEST, IS_NULL signals // that signing was never possible for this session, which Windows 11 (24H2+) // respects even when Connection.RequireSigning is TRUE from its local policy. SMB2_SESSION_FLAG_IS_NULL uint16 = 0x0002 )
── Session flags ──────────────────────────────────────────────────────────
const ( SMB2_DIALECT_202 uint16 = 0x0202 SMB2_DIALECT_210 uint16 = 0x0210 )
── Dialect revisions ──────────────────────────────────────────────────────
const ( FILE_ATTRIBUTE_READONLY uint32 = 0x00000001 FILE_ATTRIBUTE_DIRECTORY uint32 = 0x00000010 FILE_ATTRIBUTE_ARCHIVE uint32 = 0x00000020 FILE_ATTRIBUTE_NORMAL uint32 = 0x00000080 )
── File attributes ────────────────────────────────────────────────────────
const ( FILE_SUPERSEDE uint32 = 0x00000000 FILE_OPEN uint32 = 0x00000001 FILE_CREATE uint32 = 0x00000002 FILE_OPEN_IF uint32 = 0x00000003 FILE_OVERWRITE uint32 = 0x00000004 FILE_OVERWRITE_IF uint32 = 0x00000005 )
── Create disposition ─────────────────────────────────────────────────────
const ( FILE_SUPERSEDED uint32 = 0x00000000 FILE_OPENED uint32 = 0x00000001 FILE_CREATED uint32 = 0x00000002 FILE_OVERWRITTEN uint32 = 0x00000003 )
── Create action (response) ───────────────────────────────────────────────
const ( FILE_DIRECTORY_FILE uint32 = 0x00000001 FILE_NON_DIRECTORY_FILE uint32 = 0x00000040 FILE_DELETE_ON_CLOSE uint32 = 0x00001000 )
── Create options ─────────────────────────────────────────────────────────
const ( FILE_BOTH_DIR_INFORMATION uint8 = 3 FILE_ID_BOTH_DIR_INFORMATION uint8 = 37 )
── QueryDirectory info classes ────────────────────────────────────────────
const ( SMB2_RESTART_SCANS uint8 = 0x01 SMB2_RETURN_SINGLE_ENTRY uint8 = 0x02 SMB2_INDEX_SPECIFIED uint8 = 0x04 SMB2_REOPEN uint8 = 0x10 )
── QueryDir flags ─────────────────────────────────────────────────────────
const ( SMB2_0_INFO_FILE uint8 = 0x01 SMB2_0_INFO_FILESYSTEM uint8 = 0x02 SMB2_0_INFO_SECURITY uint8 = 0x03 )
── QueryInfo types ────────────────────────────────────────────────────────
const ( FileBasicInformation uint8 = 4 FileStandardInformation uint8 = 5 FileInternalInformation uint8 = 6 FileEaInformation uint8 = 7 FileAccessInformation uint8 = 8 FileNameInformation uint8 = 9 FileRenameInformation uint8 = 10 FileDispositionInformation uint8 = 13 FilePositionInformation uint8 = 14 FileModeInformation uint8 = 16 FileAllInformation uint8 = 18 FileEndOfFileInformation uint8 = 20 FileStreamInformation uint8 = 22 FileNetworkOpenInformation uint8 = 34 )
── File info classes ──────────────────────────────────────────────────────
const ( FileFsVolumeInformation uint8 = 1 FileFsSizeInformation uint8 = 3 FileFsDeviceInformation uint8 = 4 FileFsAttributeInformation uint8 = 5 FileFsFullSizeInformation uint8 = 7 FileFsObjectIdInformation uint8 = 8 )
── Filesystem info classes ────────────────────────────────────────────────
const ( FSCTL_DFS_GET_REFERRALS uint32 = 0x00060194 FSCTL_VALIDATE_NEGOTIATE_INFO uint32 = 0x00140204 FSCTL_CREATE_OR_GET_OBJECT_ID uint32 = 0x000900C0 FSCTL_QUERY_ON_DISK_VOLUME_INFO uint32 = 0x9013C FSCTL_PIPE_TRANSCEIVE uint32 = 0x0011C017 FSCTL_PIPE_WAIT uint32 = 0x00110040 FSCTL_PIPE_PEEK uint32 = 0x0011400C )
── Ioctl codes ────────────────────────────────────────────────────────────
const (
SMB2_0_IOCTL_IS_FSCTL uint32 = 0x00000001
)
── IOCTL flags ─────────────────────────────────────────────────────────────
const SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB uint16 = 0x0001
const (
SMB2_GLOBAL_CAP_LARGE_MTU uint32 = 0x00000004
)
── Capabilities ───────────────────────────────────────────────────────────
Variables ¶
This section is empty.
Functions ¶
func ChallengeToken ¶
ChallengeToken wraps an NTLMSSP Type 2 message in SPNEGO NegTokenResp. Used in the first SessionSetup response (STATUS_MORE_PROCESSING).
func DeriveNTLMv1SigningKey ¶
func DeriveNTLMv1SigningKey(password string, captured *CapturedHash) ([]byte, error)
DeriveNTLMv1SigningKey derives the SMB2 session signing key from an NTLMv1 or NTLMv1+ESS exchange. Per MS-NLMP:
NT_Hash = MD4(UTF-16LE(password)) SessionBaseKey = MD4(NT_Hash)
NTLMv1 (no ESS): KeyExchangeKey = SessionBaseKey NTLMv1+ESS: KeyExchangeKey = HMAC-MD5(SessionBaseKey, ServerChallenge || LMResponse[0:8])
If EncryptedRandomSessionKey is present (KEY_EXCH), decrypt it with RC4. For SMB2 dialect 2.x the signing key equals the ExportedSessionKey.
func DeriveNTLMv2SigningKey ¶
func DeriveNTLMv2SigningKey(password, username, effectiveDomain string, ntProofStr, encryptedSessionKey []byte) ([]byte, error)
DeriveNTLMv2SigningKey derives the SMB2 session signing key from the NTLM exchange. For dialect 2.x the signing key is the ExportedSessionKey. effectiveDomain must be the domain string that was used when verifying the NTProofStr (may be "" if the client sent no domain or the empty-domain fallback was used).
func ExtractNTLM ¶
ExtractNTLM finds the NTLMSSP token within a SPNEGO security blob. It handles both wrapped (SPNEGO) and bare NTLMSSP tokens.
func FinalToken ¶
func FinalToken() []byte
FinalToken returns a SPNEGO NegTokenResp indicating accept-completed. Used in the second SessionSetup response (STATUS_SUCCESS).
func InitialSPNEGO ¶
func InitialSPNEGO() []byte
InitialSPNEGO returns the security blob for the SMB2 Negotiate response. It advertises NTLMSSP as the only supported mechanism.
func NTLMv1Verify ¶
func NTLMv1Verify(captured *CapturedHash, password string) bool
NTLMv1Verify checks whether a captured NTLMv1 (or NTLMv1+ESS) NT response matches the given password.
func NTLMv2Verify ¶
func NTLMv2Verify(captured *CapturedHash, password string) bool
NTLMv2Verify checks if the captured NTProofStr matches the provided password.
func NegTokenRespSelectNTLM ¶
func NegTokenRespSelectNTLM() []byte
NegTokenRespSelectNTLM returns a SPNEGO NegTokenResp that tells the client the server selected NTLMSSP as the authentication mechanism. Used in response to a client NegTokenInit that carries only mechTypes (no embedded NTLM token). The client will then send a full NTLM Type 1 next.
func SignSMB2Response ¶
func SignSMB2Response(signingKey, message []byte)
SignSMB2Response computes an HMAC-SHA256 signature over the SMB2 response and writes it into the Signature field (bytes 48-63). The FLAGS_SIGNED bit is also set in the Flags field. The message slice is modified in-place.
func TryCrackDefault ¶
func TryCrackDefault(captured *CapturedHash) (string, bool)
TryCrackDefault tries the built-in wordlist only. Safe to call synchronously — ~100 candidates, sub-millisecond.
func TryCrackFile ¶
func TryCrackFile(captured *CapturedHash, wordlistPath string) (string, bool)
TryCrackFile streams wordlistPath line-by-line and returns the first match. Intended to be called in a goroutine for large lists — do not block the SMB response on this.
Types ¶
type CapturedHash ¶
type CapturedHash struct {
Username string
Domain string
Workstation string
Protocol NTLMProtocol // detected authentication variant
HashcatMode string // hashcat -m value matching Protocol
ServerChallenge [8]byte
// NTLMv1 fields
LMResponse []byte // 24-byte LM response (or client nonce padded for ESS)
NTResponse []byte // 24-byte NT response
// NTLMv2 fields
NTProofStr []byte
Blob []byte
HashcatLine string // ready-to-use hashcat line
EncryptedRandomSessionKey []byte // for SMB2 session signing key derivation
}
CapturedHash holds all fields needed to reproduce a captured NTLM hash. Depending on Protocol, different fields are populated:
NTLMv1 / NTLMv1+ESS: LMResponse, NTResponse NTLMv2: NTProofStr, Blob
type NTLMChallenge ¶
type NTLMChallenge struct {
ServerChallenge [8]byte
TargetName string
DowngradeLevel NTLMDowngradeLevel
ClientFlags uint32 // negotiate flags from the client's Type 1 message
}
NTLMChallenge holds the server-side state for a single NTLM exchange.
func NewChallenge ¶
func NewChallenge(targetName string) (*NTLMChallenge, error)
NewChallenge creates a new NTLMChallenge with a cryptographically random server challenge.
func (*NTLMChallenge) BuildChallengeMessage ¶
func (c *NTLMChallenge) BuildChallengeMessage() []byte
BuildChallengeMessage builds the NTLMSSP Type 2 (CHALLENGE) message. The flags and TargetInfo payload are chosen based on c.DowngradeLevel to attempt forcing the weakest protocol the client will accept.
func (*NTLMChallenge) ParseAuthMessage ¶
func (c *NTLMChallenge) ParseAuthMessage(msg []byte) (*CapturedHash, error)
ParseAuthMessage parses an NTLMSSP Type 3 (AUTHENTICATE) message and auto-detects the protocol used by the client (NTLMv1, NTLMv1+ESS, or NTLMv2) based on the NT/LM response lengths.
type NTLMDowngradeLevel ¶
type NTLMDowngradeLevel int
NTLMDowngradeLevel controls which protocol flags the server advertises in the Type 2 challenge, from weakest (NTLMv1) to strongest (NTLMv2).
const ( DowngradeNTLMv1 NTLMDowngradeLevel = 0 // no ESS → elicit NTLMv1 responses DowngradeNTLMv1ESS NTLMDowngradeLevel = 1 // ESS without TARGET_INFO → elicit NTLMv1+ESS DowngradeNTLMv2 NTLMDowngradeLevel = 2 // full flags → accept NTLMv2 (no downgrade) )
func (NTLMDowngradeLevel) String ¶
func (d NTLMDowngradeLevel) String() string
type NTLMProtocol ¶
type NTLMProtocol string
NTLMProtocol identifies which authentication variant a client used.
const ( ProtoNTLMv1 NTLMProtocol = "NetNTLMv1" ProtoNTLMv1ESS NTLMProtocol = "NetNTLMv1+ESS" ProtoNTLMv2 NTLMProtocol = "NetNTLMv2" )
type SMBServer ¶
type SMBServer struct {
IP string
Port int // default 445
Root string // directory to serve
ServerName string // NetBIOS name advertised in NTLM, e.g. "GOSHS"
Username string // username for authentication
Password string // password for authentication
Domain string // domain for authentication
ReadOnly bool
UploadOnly bool
NoDelete bool
Wordlist string // optional wordlist path for quick hash cracking
Hub *ws.Hub
WebHook *webhook.Webhook
// contains filtered or unexported fields
}
SMBServer is the SMB2 file server + NTLM hash capture server.