shadow1ng/fscan · error

failed to tree connect AndX: %s

Error message

failed to tree connect AndX: %s

What it means

This error wraps a failure of treeConnectAndX in smb1AnonymousConnectIPC (plugins/services/ms17010_exp.go:160). treeConnectAndX sends an SMB1 Tree Connect AndX request for \\host\IPC$ using the logged-in UserID and reads the reply via smb1GetResponse; it can also fail earlier if net.SplitHostPort cannot split the address. The library throws it because the exploit needs an established IPC$ tree (TreeID) before staging the Trans2 packets.

Source

Thrown at plugins/services/ms17010_exp.go:160

			_ = 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       uint16
	Flags           uint8
	Flags2          uint16
	ProcessIDHigh   uint16
	Signature       [8]byte
	Reserved2       [2]byte

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Ensure the address is in host:port form — a missing port makes SplitHostPort fail before anything is sent
  2. Check the tree-connect response's NT status; ACCESS_DENIED means IPC$ null sessions are blocked on the target
  3. Inspect the wrapped smb1GetResponse error for reset vs timeout and retry accordingly
  4. Confirm the anonymous login succeeded (valid UserID) since an invalid UserID can cause the tree connect to be rejected

Example fix

// before
header, err = treeConnectAndX(conn, address, header.UserID)
if err != nil {
    return nil, nil, fmt.Errorf("failed to tree connect AndX: %s", err)
}
// after
if _, _, err := net.SplitHostPort(address); err != nil {
    return nil, nil, fmt.Errorf("invalid address %q (want host:port): %w", address, err)
}
header, err = treeConnectAndX(conn, address, header.UserID)
if err != nil {
    return nil, nil, fmt.Errorf("failed to tree connect AndX: %w", err)
}
Defensive patterns

Strategy: validation

Validate before calling

func validTargetAddress(address string) error {
    host, port, err := net.SplitHostPort(address)
    if err != nil {
        return fmt.Errorf("address %q must be host:port: %w", address, err)
    }
    if net.ParseIP(host) == nil {
        return fmt.Errorf("host %q is not an IP", host)
    }
    _, err = strconv.Atoi(port)
    return err
}

Type guard

func isAddressFormatErr(err error) bool {
    var addrErr *net.AddrError
    return errors.As(err, &addrErr) && addrErr.Err == "missing port in address"
}

Try / catch

header, conn, err := smb1AnonymousConnectIPC(addr)
if err != nil {
    if isAddressFormatErr(err) || strings.Contains(err.Error(), "failed to tree connect AndX") && missingPort(addr) {
        addr = net.JoinHostPort(addr, "445")
        return smb1AnonymousConnectIPC(addr)
    }
    return err
}

Prevention

When it happens

Trigger: net.SplitHostPort fails on a malformed address (no host:port form), the packet write fails, or smb1GetResponse fails on the tree-connect reply (NetBIOS read error/timeout, invalid message type, response shorter than 32 bytes, incomplete body, unparseable header).

Common situations: Address passed without a port (e.g. "10.0.0.5" instead of "10.0.0.5:445"); server denies access to IPC$ even for anonymous sessions; connection dropped mid-session by the target or an IDS; timeouts on slow targets.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/a64473d09870a610. Report an issue: GitHub.