shadow1ng/fscan · error

ms17010_shellcode_decode_failed: %w

Error message

ms17010_shellcode_decode_failed: %w

What it means

The plugin failed to hex-decode the shellcode string before feeding it to EternalBlue. Go's hex.DecodeString requires an even-length string of [0-9a-fA-F]; this error wraps that decode failure. The library throws it because the shellcode input was not valid hex, so no byte payload can be constructed.

Source

Thrown at plugins/services/ms17010.go:469

			read, err := os.ReadFile(shellcode[5:])
			if err != nil {
				return fmt.Errorf("%s: %w", i18n.GetText("ms17010_shellcode_file_read_failed"), err)
			}
			sc = fmt.Sprintf("%x", read)
		} else {
			sc = shellcode
		}
	}

	// 验证shellcode有效性
	if len(sc) < 20 {
		return fmt.Errorf("%s", i18n.GetText("ms17010_invalid_shellcode"))
	}

	// 解码shellcode
	scBytes, err := hex.DecodeString(sc)
	if err != nil {
		return fmt.Errorf("%s: %w", i18n.GetText("ms17010_shellcode_decode_failed"), err)
	}

	if err = eternalBlue(net.JoinHostPort(info.Host, "445"), 12, 12, scBytes); err != nil {
		return fmt.Errorf("MS17-010 exp failed: %w", err)
	}

	session.LogSuccess(i18n.Tr("ms17010_shellcode_complete", info.Host, len(scBytes)))
	return nil
}

// init 自动注册插件
func init() {
	// 使用高效注册方式:直接传递端口信息,避免实例创建
	RegisterPluginWithPorts("ms17010", func() Plugin {
		return NewMS17010Plugin()
	}, []int{445})
}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Convert the shellcode to plain lowercase hex with no prefixes, whitespace, or separators (e.g. with Python: `open('sc.bin','rb').read().hex()`, or msfvenom -f hex).
  2. Remove "0x", commas, quotes, "\\x" sequences, and any whitespace/newlines from the string.
  3. Ensure the hex string has an even number of characters.
  4. Check the wrapped %w error in logs — it names the exact byte position and invalid character that broke decoding.
  5. If loading from a file, make sure the file contains hex text, not raw binary (the plugin hex-formats the raw bytes itself via %x, so raw binary in a `file:` path is actually fine — only non-binary garbage like text fails).

Example fix

// before
shellcode = "\xfc\x48\x83\xe4\xf0\xe8"          // \x-escaped, not hex text
// after
shellcode = "fc4883e4f0e8"                          // plain hex, even length
Defensive patterns

Strategy: validation

Validate before calling

sc := strings.Map(func(r rune) rune { return unicode.ToLower(r) }, strings.TrimSpace(rawShellcode))
if len(sc) == 0 || len(sc)%2 != 0 {
    return errors.New("shellcode hex string must have even, non-zero length")
}
if _, err := hex.DecodeString(sc); err != nil {
    return fmt.Errorf("invalid hex shellcode: %w", err)
}

Type guard

func isHexString(s string) bool {
    if len(s) == 0 || len(s)%2 != 0 { return false }
    _, err := hex.DecodeString(s)
    return err == nil
}

Try / catch

scBytes, err := hex.DecodeString(sc)
if err != nil {
    return fmt.Errorf("shellcode is not valid hex (pos %v): %w", err, err)
}

Prevention

When it happens

Trigger: Setting config.Shellcode to a raw string that is not hex (e.g. shellcode containing "\xfc\x48\x83..." escaped bytes, base64, or non-hex characters); a `file:`-referenced file whose content is not hex; or an odd-length hex string.

Common situations: Pasting Metasploit/Cobalt Strike shellcode in \x-escaped or raw binary form instead of plain hex; using a C-array string like "\xfc\xe8..."; copying hex with whitespace, 0x prefixes, or a trailing newline; providing an odd number of hex digits.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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