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

  1. 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).
  2. If using `file:<path>`, ensure the file contains real shellcode bytes, not an empty or placeholder file.
  3. 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.
  4. 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

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


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