shadow1ng/fscan · error

ms17010_shellcode_decode_failed

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.

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.

Appendix: 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)