Skip to content

imail SMTP AUTH PLAIN 未认证远程拒绝服务漏洞报告 #131

Description

@Ch1ps-dot

imail SMTP AUTH PLAIN 未认证远程拒绝服务漏洞报告

概述

imail SMTP 服务在处理 AUTH PLAIN 认证数据时,未校验 base64 解码后的字段数量,直接访问 strings.SplitN(..., "\x00", 3) 返回切片的固定下标。远程攻击者无需认证,只需向 SMTP 端口发送畸形 AUTH PLAIN 数据,即可触发 Go runtime panic,导致 imail 进程退出,造成拒绝服务。

影响组件

  • 协议:SMTP
  • 文件:internal/smtpd/smtpd.go
  • 函数:cmdAuthPlainLogin
  • 触发点:list[1]list[2]
  • 默认影响端口:25465

漏洞类型

  • CWE-20: Improper Input Validation
  • CWE-248: Uncaught Exception
  • 影响:未认证远程拒绝服务

漏洞成因

代码位置:internal/smtpd/smtpd.go

func (smtp *SmtpdServer) cmdAuthPlainLogin(input string) (bool, bool) {
    if strings.HasPrefix(input, stateList[CMD_AUTH_PLAIN]) {
        inputN := strings.SplitN(input, " ", 3)
        if len(inputN) == 3 {
            data := smtp.base64Decode(inputN[2])

            list := strings.SplitN(data, "\x00", 3)

            userList := strings.Split(list[1], "@")

            smtp.loginUser = userList[0]
            smtp.loginPwd = list[2]
        }
    }
}

安全影响

攻击者可通过单次 SMTP 连接触发 imail 进程崩溃。由于 SMTP 通常对公网开放,该漏洞可能导致邮件收发服务和同进程 Web 服务中断。反复触发可造成持续拒绝服务。

修复建议

  1. 校验 AUTH PLAIN base64 解码结果必须包含三个字段。
  2. 访问 list[1]list[2] 前检查 len(list) == 3
  3. 对空用户名、空密码、非法用户名格式返回认证失败。
  4. 在连接处理 goroutine 顶层增加 recover,避免单连接异常导致整个进程退出。

示例修复:

list := strings.SplitN(data, "\x00", 3)
if len(list) != 3 {
    smtp.write(MSG_AUTH_FAIL)
    return true, false
}

if strings.TrimSpace(list[1]) == "" || strings.TrimSpace(list[2]) == "" {
    smtp.write(MSG_AUTH_FAIL)
    return true, false
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions