shadow1ng/fscan · error
failed to get OS name: %s
Error message
failed to get OS name: %s
What it means
This error wraps a failure of getOSName after the anonymous login reply is received (plugins/services/ms17010_exp.go:155). getOSName parses the UTF-16 native-OS string that starts 10 bytes after the SMB header (raw[smbHeaderSize+10:]) and scans until a 0x0000 terminator; it returns an error when the buffer runs out before finding one (io.ErrUnexpectedEOF / io.EOF from io.ReadFull). The library throws it because the login response did not carry a well-formed native OS string.
Source
Thrown at plugins/services/ms17010_exp.go:155
return nil, nil, fmt.Errorf("failed to connect host: %s", err)
}
var ok bool
defer func() {
if !ok {
_ = conn.Close()
}
}()
err = smbClientNegotiate(conn)
if err != nil {
return nil, nil, fmt.Errorf("failed to negotiate: %s", err)
}
raw, header, err := smb1AnonymousLogin(conn)
if err != nil {
return nil, nil, fmt.Errorf("failed to login with anonymous: %s", err)
}
_, err = getOSName(raw)
if err != nil {
return nil, nil, fmt.Errorf("failed to get OS name: %s", err)
}
//fmt.Println("OS:", osName)
header, err = treeConnectAndX(conn, address, header.UserID)
if err != nil {
return nil, nil, fmt.Errorf("failed to tree connect AndX: %s", err)
}
ok = true
return header, conn, nil
}
const smbHeaderSize = 32
type smbHeader struct {
ServerComponent [4]byte
SMBCommand uint8
ErrorClass uint8
Reserved byte
ErrorCode uint16View on GitHub (pinned to 95cc12e753)
Solutions
- Dump the raw login response (hexdump) to confirm whether a Native OS string is present at the expected offset
- Treat hosts failing this parse as non-Windows/odd SMB stacks and skip them for EternalBlue
- Make the parser tolerant: check len(raw) >= smbHeaderSize+10 before scanning and return a descriptive error if too short
- Verify the login actually succeeded (NT status in the header) before attempting the OS-string parse
Example fix
// before
_, err = getOSName(raw)
if err != nil {
return nil, nil, fmt.Errorf("failed to get OS name: %s", err)
}
// after
if len(raw) < smbHeaderSize+10 {
return nil, nil, fmt.Errorf("login response too short for OS name: %d bytes", len(raw))
}
if _, err = getOSName(raw); err != nil {
return nil, nil, fmt.Errorf("failed to get OS name: %w", err)
} Defensive patterns
Strategy: type-guard
Validate before calling
func hasOSNameField(raw []byte) bool {
return len(raw) >= smbHeaderSize+10 // parser starts at raw[smbHeaderSize+10:]
} Type guard
func parseableLoginResponse(raw []byte) bool {
if len(raw) < smbHeaderSize+10 { return false }
return bytes.Equal(raw[0:4], []byte{0xFF, 0x53, 0x4D, 0x42}) // \xffSMB
} Try / catch
raw, header, err := smb1AnonymousLogin(conn)
if err == nil && !parseableLoginResponse(raw) {
// skip OS-name parsing; header may still be usable
}
_, err = getOSName(raw)
if err != nil {
return fmt.Errorf("non-standard SMB stack (no Native OS string): %w", err)
} Prevention
- Don't require the OS string for hosts known to run Samba/embedded SMB stacks
- Check response length before slicing offsets derived from smbHeaderSize
- Verify the NT status in the response header before parsing the body
- Use OS-name failure as a signal of non-Windows targets rather than a fatal condition
When it happens
Trigger: smb1AnonymousConnectIPC receives a login response whose bytes after offset smbHeaderSize+10 do not contain the expected UTF-16 string terminated by 0x0000 — e.g. the response is too short (near or below 42 bytes) or the layout deviates (server sent an error response instead of a session-setup reply).
Common situations: Non-Windows or embedded SMB implementations (Samba variants, NAS, printers) that omit or relocate the Native OS field; servers replying with a DOS error-format response rather than the expected AndX reply; truncated responses from flaky networks.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- failed to negotiate: %s
- failed to login with anonymous: %s
- failed to tree connect AndX: %s
- invalid message type 0x%02X in SMB1 response
- parser_cidr_failed: %w
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/f35273cc5f31c952.
Report an issue: GitHub.