shadow1ng/fscan · error
ms17010_invalid_shellcode
Error message
ms17010_invalid_shellcode
What it means
The MS17-010 plugin rejects a shellcode string shorter than 20 hex characters (<10 bytes) before attempting EternalBlue. The library throws it because a payload that small cannot contain a meaningful kernel/user payload, and running the exploit with it would waste attempts or crash the target. It acts as an input sanity check on the resolved shellcode string (from config, file, or decrypted preset).
Source
Thrown at plugins/services/ms17010.go:463
sc = ""
default:
// 从文件读取或直接使用提供的shellcode
shellcode := config.Shellcode
if strings.Contains(shellcode, "file:") {
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() {View on GitHub (pinned to 95cc12e753)
Solutions
- Set config.Shellcode to a valid payload type ("bind", "add", "guest") or a hex-encoded shellcode string of at least 10 bytes (20 hex chars).
- If using `file:<path>`, ensure the file contains real shellcode bytes, not an empty or placeholder file.
- Avoid the built-in "cs" value unless you have patched the plugin to supply the actual CS payload, since it resolves to an empty string and always fails.
- Validate the hex string length client-side before launching the scan (see defense strategies).
Example fix
// before (config) shellcode = "cs" // resolves to empty string, always fails // after shellcode = "bind" // or a hex string like "fc4883e4f0e8c0..." (>= 20 hex chars)
Defensive patterns
Strategy: validation
Validate before calling
sc := strings.TrimSpace(config.Shellcode)
if sc == "cs" || len(sc) < 20 {
return fmt.Errorf("shellcode must be a hex string of >= 20 chars; got %q (len=%d)", sc, len(sc))
} Type guard
func isValidShellcode(sc string) bool {
return len(sc) >= 20 && len(sc)%2 == 0 && regexp.MustCompile(`^[0-9a-fA-F]+$`).MatchString(sc)
} Prevention
- Never leave Shellcode set to "cs" unless the plugin provides the actual CS payload.
- Pre-validate shellcode length and hex-ness in a startup config check.
- When using `file:` paths, assert the file is non-empty and >= 10 bytes before scanning.
- Log the resolved shellcode length at debug level to catch truncation early.
When it happens
Trigger: Calling the ms17010 plugin with config.Shellcode set to "cs" (hardcoded to empty string at ms17010.go:445), a custom shellcode string of fewer than 20 characters, or a `file:`-referenced file shorter than 10 bytes — any path where the final `sc` string length < 20.
Common situations: Operators leaving Shellcode="cs" in the config without supplying an actual Cobalt Strike payload elsewhere; pasting a truncated hex string; pointing `file:` at an empty or stub file; or a decryption path silently yielding a short/garbage string.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- ms17010_shellcode_decode_failed: %w
- i18n.GetText("ms17010_not_vulnerable")
- i18n.GetText("ms17010_base64_decode_failed"): %w
- i18n.GetText("ms17010_aes_cipher_failed"): %w
- i18n.GetText("ms17010_ciphertext_too_short")
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/6e914802516e2458.
Report an issue: GitHub.