Summary
RubySMB's SMB1 implementation does not work with Windows 95/98/ME and other pre-NT legacy SMB hosts. These systems predate many assumptions baked into the library and require
protocol paths that are either missing or broken.
Will send PR soon to fix this.
Windows 95/98/ME compatibility gaps
No port 445
Windows 9x predates the Windows 2000 introduction of direct SMB over TCP (port 445). These hosts only listen on port 139 (NetBIOS Session Service). Connections must use direct: false to perform the NetBIOS session setup handshake before SMB negotiation. Any code that defaults to port 445 or skips the NetBIOS layer will fail to connect.
No extended security (NTLMSSP)
Windows 9x does not support extended security negotiation. The negotiate response does not set the extended_security flag, and session setup must use the legacy LM/NTLM
authentication path (SessionSetupLegacyRequest/SessionSetupLegacyResponse) rather than NTLMSSP blobs.
Share-level authentication
Windows 9x uses share-level security, not user-level. Passwords are per-share, not per-user. The password is sent in the TreeConnectRequest.data_block.password field as plaintext.
The smb1_tree_connect method accepts a password: keyword argument for this, but higher-level APIs and Metasploit modules generally do not expose it.
TreeConnectRequest password field serialization
The password field in TreeConnectRequest::DataBlock is declared as BinData::Stringz, which always appends a null terminator when serializing, regardless of the length
parameter. With password_length set to N, the field writes N+1 bytes instead of N, corrupting the share path that follows. This breaks any use case that requires exact control over
the password byte count, such as CVE-2000-0979 (Windows 9x share password byte-by-byte enumeration).
No DCERPC/SRVSVC
Windows 9x does not support DCERPC or the SRVSVC named pipe. Calling net_share_enum_all (which binds to SRVSVC) fails with DBG_CONTINUE. Share enumeration must use the RAP
(Remote Administration Protocol) via \PIPE\LANMAN. RubySMB has net_share_enum_rap for this, but it is not the default path and callers must know to use it.
No TRANS2 FIND_FIRST2
Windows 9x returns ERRDOS/ERRnomem for TRANS2 FIND_FIRST2 directory listing requests. File listing on these hosts requires SMB_COM_SEARCH (command 0x81), a core protocol
command that returns 8.3 filenames in 43-byte entries. RubySMB does not implement this command.
Environment
- RubySMB version: 3.3.17 (current master)
- Targets tested: Windows 95 (4.00.950), Windows 98 SE
- Connection: port 139, SMB1 only,
direct: false
Summary
RubySMB's SMB1 implementation does not work with Windows 95/98/ME and other pre-NT legacy SMB hosts. These systems predate many assumptions baked into the library and require
protocol paths that are either missing or broken.
Will send PR soon to fix this.
Windows 95/98/ME compatibility gaps
No port 445
Windows 9x predates the Windows 2000 introduction of direct SMB over TCP (port 445). These hosts only listen on port 139 (NetBIOS Session Service). Connections must use
direct: falseto perform the NetBIOS session setup handshake before SMB negotiation. Any code that defaults to port 445 or skips the NetBIOS layer will fail to connect.No extended security (NTLMSSP)
Windows 9x does not support extended security negotiation. The negotiate response does not set the
extended_securityflag, and session setup must use the legacy LM/NTLMauthentication path (
SessionSetupLegacyRequest/SessionSetupLegacyResponse) rather than NTLMSSP blobs.Share-level authentication
Windows 9x uses share-level security, not user-level. Passwords are per-share, not per-user. The password is sent in the
TreeConnectRequest.data_block.passwordfield as plaintext.The
smb1_tree_connectmethod accepts apassword:keyword argument for this, but higher-level APIs and Metasploit modules generally do not expose it.TreeConnectRequest password field serialization
The password field in
TreeConnectRequest::DataBlockis declared asBinData::Stringz, which always appends a null terminator when serializing, regardless of thelengthparameter. With
password_lengthset to N, the field writes N+1 bytes instead of N, corrupting the share path that follows. This breaks any use case that requires exact control overthe password byte count, such as CVE-2000-0979 (Windows 9x share password byte-by-byte enumeration).
No DCERPC/SRVSVC
Windows 9x does not support DCERPC or the SRVSVC named pipe. Calling
net_share_enum_all(which binds to SRVSVC) fails withDBG_CONTINUE. Share enumeration must use the RAP(Remote Administration Protocol) via
\PIPE\LANMAN. RubySMB hasnet_share_enum_rapfor this, but it is not the default path and callers must know to use it.No TRANS2 FIND_FIRST2
Windows 9x returns
ERRDOS/ERRnomemfor TRANS2FIND_FIRST2directory listing requests. File listing on these hosts requiresSMB_COM_SEARCH(command 0x81), a core protocolcommand that returns 8.3 filenames in 43-byte entries. RubySMB does not implement this command.
Environment
direct: false