mssrvs:
- NetShareEnumAllExt enumerates shares at info levels 501 and 502 in
addition to level 1; NetShareEnumAll now delegates to it. Level 501 adds
Flags; level 502 adds Permissions, MaxUses, CurrentUses, Path and the
parsed SecurityDescriptor on each NetShare.
- NetShareGetInfo[Ext] queries a single share at levels 0/1/2/501/502.
- NetShareSetInfo plus NetShareSetInfoComment/Flags/SecurityDescriptor
convenience setters (levels 1004/1005/1501 and the 1/2/502 unions).
- NetServerDiskEnum enumerates the server's disk drives (level 0).
- New SHARE_INFO_{0,2,501,502,1004,1005,1501} structs and the SHARE_INFO
switch union, with NDR marshalling and round-trip tests.
msscmr:
- GetServiceSecurity[Bytes]/SetServiceSecurity[Bytes] (Opnum 4/5,
RQueryServiceObjectSecurity/RSetServiceObjectSecurity) and
GetSCManagerSecurity[Bytes] read and write service and SCM-database
security descriptors.
- Open SCM/service handles with least privilege: openSCManager uses
SC_MANAGER_CONNECT and each method opens the service with only the rights
it needs (DeleteService -> DELETE; ChangeServiceConfig2 derives rights
from the requested config via ConfigInfoW.RequiredServiceAccess).
- Add SECURITY_INFORMATION and standard-access-right constants; drop the
unused scActionBuf.
smb:
- QueryInfoSecurityRaw returns the full parsed SecurityDescriptor (every
ACE and its raw access mask) with a buffer-overflow retry; QueryInfoSecurity
delegates to it and tolerates a descriptor with no owner/group/DACL.
- OpenFileReadAttributes opens a handle with READ_CONTROL only, enough to
read a security descriptor without data-read access.
go-smb and github.com/jfjallid/ldap/v3 were mutually dependent modules:
go-smb/ldap wraps ldap/v3, while ldap/v3 reached back into go-smb/{gss,
krb5ssp,ntlmssp}. Because krb5ssp.KRB5Token carries gokrb5 types across that
boundary, the two were also pinned to the same gokrb5 major version. ldap/v3
v3.101.0 severs that cycle (it no longer imports go-smb); this is the go-smb
side of the change.
krb5ssp:
- Migrate from gokrb5/v8 to gokrb5/v9 (krb5ssp.go, wrapToken.go, the
ccache_{linux,darwin,windows}.go ccache loaders and tests). No behaviour
change; the v9 API is source-compatible for the surface we use.
ldap:
- ldap/v3 now inverts its NTLM dependency instead of importing go-smb/ntlmssp.
Add ldap/ntlm.go: an ntlmssp.Client-backed adapter implementing ldap's
NTLMNegotiator plus the optional NTLMChannelBinder and NTLMSessionProvider
capabilities, registered as ldap.NTLMNegotiatorFactory in init(). Importing
go-smb/ldap therefore restores out-of-the-box NTLM binds; the wrapper's
credential-based NTLMChallengeBind path is unchanged and now resolves the
negotiator through this factory.
go.mod:
- gokrb5/v8 -> gokrb5/v9 v9.0.0; ldap/v3 v3.100.0 -> v3.101.0. gokrb5 is now an
ordinary shared dependency resolved by MVS.
Add the relay/ package: listen for inbound SMB or HTTP NTLM
authentications, forward them to one or more upstream targets (SMB,
HTTP/S, LDAP/S), pool the resulting authenticated sessions, and
optionally expose the pool to local tools through a SOCKS5 proxy.
Provides RelayServer (long-running multi-target listener with a session
pool, post-auth actions and optional fake-server handoff) and
RelayClient (one-shot listener returning a single authenticated
*smb.Connection), replacing the retired in-package smb.NewRelayConnection.
Add the smb.Connection hooks the relay drives: MarkAuthenticated promotes
a manually-driven SessionSetup to authenticated state, and SendRawPDU
forwards an opaque SMB2 PDU on a pooled connection (re-stamping
MessageID and applying signing/encryption).
Implement the server (request-decode / response-encode) direction of the
core DCERPC PDUs that were previously NOT IMPLEMENTED stubs:
BindReq.UnmarshalBinary, BindRes.MarshalBinary, RequestReq.UnmarshalBinary
and RequestRes.MarshalBinary, including auth-verifier and auth-pad
handling.
Add a transport-agnostic DCERPC server that binds presentation contexts
and dispatches Request PDUs to registered operations, and a MS-SRVS
(Server Service) server backing NetShareEnum so the SMB server can answer
share enumeration over \PIPE\srvsvc. Mark ShareInfo1 Name/Comment with the
notnullptr ndr tag so empty comments serialize as a non-null pointer to an
empty string, matching Windows.
Add an SMB2/3 server: connection dispatch loop, NEGOTIATE (incl. negotiate
contexts, preauth-integrity, signing/encryption capabilities), SESSION_SETUP
driven by the SPNEGO/NTLM acceptor, TREE_CONNECT, and the CREATE / READ /
WRITE / FLUSH / CLOSE / QUERY_DIRECTORY / QUERY_INFO / SET_INFO / IOCTL /
ECHO / CANCEL handlers, including named-pipe support and compound-request
chains.
Files are served through a small VFS interface with two backends: an
in-memory store (memvfs) and a passthrough to the local filesystem
(filevfs). Includes signing (HMAC-SHA256 / AES-CMAC / AES-GMAC) and
per-message encryption.
Add ntlmssp.Server, the acceptor counterpart to the NTLM client: it
consumes a NEGOTIATE, emits a CHALLENGE, and validates the AUTHENTICATE
message. Wrap it in spnego.Acceptor so the SMB/HTTP server paths can
drive SPNEGO-negotiated NTLM auth and recover the established session
key. Includes acceptor round-trip tests.
Client/shared plumbing that the upcoming server and relay packages build
on:
- signing: introduce smbSigner/smbVerifier interfaces (signer.go) and an
AES-GMAC implementation; SessionSetup wires CMAC/HMAC-SHA256/GMAC
through them, and key derivation is gated on negotiated encryption.
- negotiate: add an SMB2Only option, validate the server-selected dialect
against the offered list, support a direct SMB 2.0.2 selection and a
configurable cipher offer; accept AES_GMAC as a signing algorithm.
- credits: stop hardcoding CreditCharge=1 in the SMB2 header; 2.0.2
reserves the field (must be 0) while later dialects consume one credit
by default (applyCreditCharge), and Negotiate consumes one sequence
slot even with CreditCharge=0.
- NegotiateReq now emits the real ClientGuid (was zeroed) and decodes
SecurityMode; pointer-receiver MarshalBinary dispatch and an
offset-emptiness check land in the encoder, with regression tests.
- server-direction marshalling scaffolding (marshal_server.go, Echo/Flush
structs) and retire the old in-package relay internals (RelayPort
option, NewRelayConnection) in favour of a new relay/ package; keep
the generic SessionSetup structs and add the SendSessionSetup*WithBlob
helpers the relay drives.
Advertise NTLMSSP_NEGOTIATE_ALWAYS_SIGN in the client's NEGOTIATE
message, matching what Windows clients send and what servers expect
when negotiating signing.
Set UDPPreferenceLimit=1 unconditionally so AS/TGS exchanges go over TCP
from the start. Against AD the PAC-bearing replies almost always exceed
the UDP datagram limit, so the UDP attempt just earns a
KRB_ERR_RESPONSE_TOO_BIG and a mandatory TCP retry; skipping it avoids
the wasted round-trip and the confusing failure mode.
Add the aes128-cts-hmac-sha256-128 (19) and aes256-cts-hmac-sha384-192
(20) encryption types to the etype constants and name map so extracted
Kerberos keys of these types are recognised and rendered correctly.
Check the operation return code against the status map in msrrp, mssamr
and mslsad calls, returning the mapped error (or an explicit "unknown
return code 0x..." for unmapped values).
Add the LSA SOME_NOT_MAPPED / NONE_MAPPED / TRUSTED_DOMAIN_FAILURE
statuses and treat SOME_NOT_MAPPED as partial success in the
SID/name lookups.
Also drop the manual trailing-null trimming of registry key/value names
in msrrp now that the ndr decoder strips it.
BinaryPathName, ServiceStartName and DisplayName are optional in
RChangeServiceConfigW (a null pointer means "no change"). Model them as
*string in the request struct and plumb pointers through
ChangeServiceConfig/ChangeServiceConfigExt so callers can omit fields
instead of forcing empty strings.
Parse and marshal the object-ACE family (MS-DTYP 2.4.4.3-2.4.4.6):
read the Flags field and the optional ObjectType / InheritedObjectType
GUIDs (gated by IsObjectAceType) before the SID, leaving plain ACEs
untouched so existing Mask/Sid callers are unaffected. Expose the GUIDs
through AcePermissions and add GuidToString/GuidFromString for the
little-endian object-ACE wire layout, with round-trip tests.
(cifs/ldap/www/http/rpcss/dcom -> host by default), exposed via a new
SPNAliases field on spnego.KRB5Initiator and a new spnAliases parameter on
krb5ssp.InitKerberosClient/InitKerberosClientExt. The ccache lookup now uses
gokrb5's NewFromCCacheWithFallbacks to try the requested SPN first and then
each configured alias in order. Bumped gokrb5 to v8.6.1 (and crypto/net) to
pick up the new fallback API and the (Client, error) return signatures on
NewWithKey/Hash/Password. Added a KRB5Initiator.Client() accessor that lazily
initializes the Kerberos client so other consumers can share credentials and
the ST cache with the DCERPC SPNEGO path. Reduced log noise in mssamr
enumerations and msdrsr DRSBind/DSA GUID selection by demoting Infof to Debugf,
mapped DRSUAPI CrackNames status codes to readable names in error messages,
and fixed resolveTarget to recognize UPNs (containing '@') and fall through to
DSUnknownName instead of misclassifying them.
When looking for service tickets in cache for cifs SPN, fallback to host SPN when cifs is missing.
Implemented RFC 4757 RC4 Wrap/MIC tokens to support both RC4 and AES for DCERPC.
Also changed to always require ServiceAllAccess when attempting to modify a service's settings.
Changed struct encoding/decoding to use the updated NDR encoder.
Implement the DCOM DCERPC service client for remote COM object activation
and method invocation over TCP. The implementation includes:
- DCOMConnection and COMObject for managing DCOM sessions and COM objects
- IRemoteSCMActivator for COM class activation via port 135
- IRemUnknown for remote reference counting and QueryInterface
- IOXIDResolver for optional OXID resolution
- IDispatch for OLE Automation (QueryInterface, GetIDsOfNames, Invoke)
- DCOM structure marshaling/unmarshaling (OBJREF, MInterfacePointer,
ORPCTHIS/ORPCTHAT, DUALSTRINGARRAY)
- WMIClient for IWbemLevel1Login, IWbemServices, and IEnumWbemClassObject
providing Query, GetObject, and ExecMethod operations
- CIM binary encoding (MS-WMIO) for parsing class definitions and
instances, and building method input parameters with support for all
scalar types, byte arrays, and string arrays
Add a found boolean return value to QueryValue2 so callers can
distinguish missing keys from errors without string matching. Downgrade
expected-case log messages from Error to Debug in both msrrp and
IoCtlRequest.
Implement AlterContext to register additional presentation contexts on an
existing DCERPC connection. Add ObjectUUID support in request PDUs for
DCOM interface remoting. Introduce BindNakError as a typed error for
programmatic handling. Add SetSPN on KRB5Initiator for DCOM service
identity override.
Extend the Sealer interface with Sign, VerifySign, and MICSignatureSize
methods for signing without encryption. Implement for both NTLM and
Kerberos (MIC tokens). Update sealRequestPDU/unsealResponsePDU to handle
PktIntegrity where the stub is signed but not encrypted.
Implement the TSCH DCERPC service client for managing scheduled tasks
including functionality to create, retrieve, run, stop and delete
scheduled tasks.
Implement the DRSR DCERPC service client for replicating Active Directory
secrets via the DRSGetNCChanges RPC. Includes DES/AES/RC4 decryption of
replicated password hashes, PEK decryption, and NTDS secret extraction.
- dcerpc/epm: add typed floor/tower accessor methods (GetTCPPorts,
GetUDPPorts, GetIPAddresses, GetUUIDs, and per-floor helpers) with a
UUIDFloor type returning UUID string, major, and minor versions; update
GetTCPPort to delegate to GetTCPPorts; add comprehensive tests including
IP address assertion from real captured wire data
- dcerpc: add DCEStyleInitiator interface and call EnableDCEStyle() in
BindAuth so GSS_C_DCE_STYLE is only set on the DCERPC TCP path, not SMB
- dcerpc: generate a random authContextId per bind and propagate it to
every security trailer written by sealRequestPDU
- msdtyp: fix RPC_UNICODE_STRING MaxCount convention in WriteRPCUnicodeStrArray
to use MaxCount = ActualCount+1 for non-null-terminated strings per
MS-DTYP 2.3.10 (MaxLength = Length+2)
- smb/encoder: use fmt.Sprintf format verbs instead of string concatenation
in error messages
Fix broken tests, latent bugs, type duplication, and non-idiomatic Go
style.
Broken tests:
- Fix dcerpc/msrrp tests that failed to compile due to unqualified
msdtyp identifiers (AccessAllowedAceType, ContainerInheritAce, ACE,
SID, etc.) — add msdtyp. prefix throughout msrrp_test.go and
structures_test.go
Bug fixes:
- Fix ContextItem.UnmarshalBinary and ContextResList.UnmarshalBinary
in dcerpc/structures.go which silently no-op'd by reassigning the
local receiver pointer rather than dereferencing it
- Remove debug fmt.Printf left in dcerpc/mslsad/lsad.go
- Changed logger path in ntlmssp/client.go (bare "ntlmssp" → full module path)
- Fix public API typo: spnego/krb5ssp.go DialTimout → DialTimeout
Type consolidation:
- Remove duplicate Filetime, PFiletime, RPCUnicodeStr, ReturnCode types
from dcerpc/msrrp; use msdtyp equivalents throughout
- Remove duplicate SecurityDescriptor, SID, ACE, PACL types from
smb/smb.go; use msdtyp equivalents throughout smb/session.go
Idiomatic Go style:
- Replace self receiver name with short type-appropriate names across
all packages (dcerpc, msdtyp, msrrp, mslsad, mssamr, msscmr, mssrvs,
mswkst, krb5ssp, ntlmssp, smb/crypto, smb)
- Rename snake_case parameters in dcerpc/dcerpc.go to camelCase
- Replace errors.New(fmt.Sprintf(...)) with fmt.Errorf in ntlmssp
- Replace fmt.Print* calls with logger calls in smb/connection.go,
smb/smb.go, and smb/encoder/encoder.go
- Fix runSender receiver name in smb/connection.go
Clarity:
- Add defaultMaxFragSize constant for the magic number 4280 in
dcerpc/dcerpc.go; add comment explaining the send/recv size inversion
- Remove dead commented-out code (MessageSignature blocks in ntlmssp,
debug lines in encoder, stale Credits assignment in session)
Test quality:
- Replace bytes.Compare(a,b) != 0 with !bytes.Equal(a,b)
- Remove unreachable return statements after t.Fatal calls
- Replace opaque t.Error("Fail") calls with descriptive t.Errorf
messages showing expected vs actual values
Refactoring:
- Extract connectToTree helper in smb/session.go to eliminate repeated
tree-connect/disconnect boilerplate from RetrieveFile, PutFile,
deleteFileDir, Mkdir, and MkdirAll
- LsarGetUserName: whoami method to return the caller's identity
- LsarLookupSids2: Translate a list of SIDs to domains and names, including cross forest if there is a trust.
- LsarLookupNames3: Translate a list of names to their corresponding SID, including cross foreT if there is a trust.
Added a new method from MS-SRVS (NetGetFileSecurity) which can be used to retrieve the security descriptor for a file on a file share.
- The smb.FsctlStatusMap has been merged into smb.StatusMap for improved handling of response codes.
MS-SAMR:
- Added new request SamrCreateUser2InDomain to support creating machine accounts.
MS-RRP:
- Refactoring of code to put some shared structures and functions in the new MS-DTYP package.
- Added new methods to create and delete registry keys and to create, enumerate, modify and delete key values.
- Added support for interacting with HKEY_CURRENT_CONFIG, HKEY_CURRENT_USER, and HKEY_USERS.
- RegSaveKey will now use a system default ACL if no owner SID is provided.
- Fixed a limitation in GetSubKeyNames where it previously was not possible to enumerate the root key names by leaving the subkey argument empty.
- New method GetKeySecurityExt which accepts argument to decide what security information to retrieve.
- New method QueryValue2 which in addition to retrieving a value also returns the value type.
- New method QueryValueExt converts the retrieved value to the data type and returns it as an interface.
MS-DTYP:
- Added a method to parse and retrieve the entries of an DACL.