shadow1ng/fscan · error
i18n.GetText("ms17010_base64_decode_failed"): %w
Error message
i18n.GetText("ms17010_base64_decode_failed"): %w What it means
aesDecrypt wraps a base64.StdEncoding.DecodeString failure with the "ms17010_base64_decode_failed" message and the underlying error (%w). The plugin decrypts its payload/config data with this helper, so any input that is not valid canonical base64 makes the whole decrypt — and thus executeMS17010Exploit — fail.
Source
Thrown at plugins/services/ms17010.go:174
output.WriteString(i18n.GetText("ms17010_exploit_shellcode_hint") + "\n")
output.WriteString(i18n.GetText("ms17010_exploit_supported_modes") + "\n")
}
session.LogSuccess(i18n.Tr("ms17010_complete", target))
return &ExploitResult{
Success: true,
Output: output.String(),
}
}
// 以下是完整的原始MS17010检测和利用代码,保持不变
// AES解密函数 (从legacy/Base.go复制)
func aesDecrypt(crypted string, key string) (string, error) {
cryptedBytes, err := base64.StdEncoding.DecodeString(crypted)
if err != nil {
return "", fmt.Errorf("%s: %w", i18n.GetText("ms17010_base64_decode_failed"), err)
}
keyBytes := []byte(key)
block, err := aes.NewCipher(keyBytes)
if err != nil {
return "", fmt.Errorf("%s: %w", i18n.GetText("ms17010_aes_cipher_failed"), err)
}
if len(cryptedBytes) < aes.BlockSize {
return "", fmt.Errorf("%s", i18n.GetText("ms17010_ciphertext_too_short"))
}
mode := cipher.NewCBCDecrypter(block, keyBytes[:aes.BlockSize])
mode.CryptBlocks(cryptedBytes, cryptedBytes)
// 移除PKCS7填充
padding := int(cryptedBytes[len(cryptedBytes)-1])
if padding > len(cryptedBytes) || padding > aes.BlockSize {View on GitHub (pinned to 95cc12e753)
Solutions
- Validate the payload is canonical std base64 before calling: base64.StdEncoding.DecodeString in a dry run or a regex ^[A-Za-z0-9+/]*={0,2}$.
- Strip whitespace/newlines from the payload before decryption.
- If the producer used URL-safe base64, re-encode or swap the decoder to base64.URLEncoding.
- Inspect the wrapped %w error with errors.Unwrap to see the exact CorruptInputError offset.
Example fix
// before
plain, err := aesDecrypt(payload, key)
// after: sanitize and disambiguate encoding
cleaned := strings.Map(func(r rune) rune {
if unicode.IsSpace(r) { return -1 }
return r
}, payload)
if b, err := base64.StdEncoding.DecodeString(cleaned); err != nil {
return fmt.Errorf("payload not std base64: %w", err)
}
plain, err := aesDecrypt(cleaned, key) Defensive patterns
Strategy: validation
Validate before calling
if _, err := base64.StdEncoding.DecodeString(payload); err != nil {
return fmt.Errorf("payload is not valid std base64: %w", err)
} Try / catch
plain, err := aesDecrypt(payload, key)
if err != nil {
var base64Err base64.CorruptInputError
if errors.As(err, &base64Err) {
return fmt.Errorf("bad base64 at offset %d", int64(base64Err))
}
return err
} Prevention
- Strip whitespace/newlines from encoded payloads
- Standardize on std base64 (not URL-safe or hex) for payload exchange
- Round-trip test encode/decode in CI
When it happens
Trigger: Passing a crypted string containing whitespace, URL-safe base64 characters (-/ _), missing padding, or raw binary/hex to aesDecrypt (via executeMS17010Exploit).
Common situations: Payloads copy-pasted with spaces/newlines, data encoded with URLEncoding instead of StdEncoding, hex-encoded blobs mistakenly treated as base64, or corrupted config values.
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
- i18n.GetText("ms17010_aes_cipher_failed"): %w
- i18n.GetText("ms17010_ciphertext_too_short")
- ms17010_invalid_padding
- ms17010_padding_check_failed
- i18n.GetText("ms17010_not_vulnerable")
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/5ff1b666d6f90f15.
Report an issue: GitHub.