导语:DKIM和DMARC以及SPF一样,都是用来防止在邮件中进行网络钓鱼攻击的主要方法。DMIM的主要思路就是数字签名应用在邮件中,然后收件方收到邮件后进行签名验证。

概要

DKIM和DMARC以及SPF一样,都是用来防止在邮件中进行网络钓鱼攻击的主要方法。DMIM的主要思路就是数字签名应用在邮件中,然后收件方收到邮件后进行签名验证。这种方法的作用是为了验证这个邮件确实是从发送者的邮件服务器发送到收件人的信箱当中的。

本文将展示一下如何在实际攻击中如何绕过DKIM这一验证方法,在特定情况下,我们尽管改变了邮件内容,但是并不会使DKIM签名无效,从而证明这一方法的安全性的确不好。文章最后展示了如何使用DKIM使用户信任大部分邮件。

什么是DKIM

这里会给出DKIM一些介绍,他的作用是防止邮件钓鱼,以及他是如何进行工作的。如果你已经了解过了DKIM,你可以跳过这一部分。

邮件钓鱼经常用来骚扰以及攻击向量

攻击方如果很容易发送钓鱼邮件,在接收方方面不仅是一种骚扰而且还是一种潜在的危险。当人们收到钓鱼邮件时,通常情况下都会认为邮件是从发件邮箱地址栏填写的地址放松过来的。但是如果发送者的邮件是你熟悉的人,或者他看起来是非常可靠的邮箱地址,那么受到攻击的概率会大大增加。这些钓鱼邮件攻击在亚马逊,苹果,DHL,以及一些银行等公司内经常发生,一旦感染,病毒就会尝试盗取用户数据,以及感染其他用户电脑。

使用DKIM,DMARC,SPF防御钓鱼邮件

因为防御钓鱼攻击很重要,在过去几年中已经开发出了几种防御方法。目前主要使用的防御方法是SPF,DKIM以及DMARC。SPF的原理是判断来源IP是否在合理范围之内,DKIM原理是由发送域的邮件服务器在邮件中添加数字签名,收件方通过数字签名判断邮件是否被修改。DMARC将确认收件栏中的邮箱是否和SPF以及DKIM中的邮件域是否相匹配。DMARC还增加了如何处理与预期不符的邮件的策略,并向原始域发送有关此类问题的报告。这三种方法都是基于DNS来提供策略的,即域的所有者需要将域中所需要的策略添加到DNS设置的特殊的SPF当中。

对DKIM的一个简单介绍

DKIM的基本思想是发件人域中的邮件服务器在邮件中添加数字签名,收件人通过签名验证邮件是否由邮件服务器发送,签名大概格式如下:

    DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
      d=dhl.com; l=1850; s=20140901; t=1452769712;
      h=date:from:to:message-id:subject:mime-version;
      bh=yCbsFBJJ9k2VYBxKGgyNILalBP3Yzn1N8cMPQr92+zw=;
      b=bnuXrH/dSnyDR/kciZauK4HTgbcDbSFzmHR78gq+8Cdm20G56Ix169SA...

在邮件签名中,最重要的部分是:

1. d是这一个域的签名。这一部分是在DMARC检查签名中的域是否和发送者的域相匹配中用到。
2. h是应该包含在签名中的邮件头的字段列表
3. bh是邮件正文的hash
4. l是hash在邮件正文中所占的字节数。这一选项是可选的。
5. b是签名本身,包括'h'给出的字段,以及DKIM-Signature头本身。由于头部保保存的是整个正文的hash,所以b这一参数也可以作为电子签名。


除此之外,签名中还包含了使用的加密算法’a’,以及用于在DNS中寻找RSA密钥的参数’s’,规范性的方法’c’,以及时间戳’t’.

邮件头部哪些内容应该进行签名

如上所述,签名应该包括正文以及相应的头部字段,并且包含的字段内容在’h’中已经给出。这里需要理解的是签名每次都会匹配’h’字段中给出的第一个头信息。因此,如果标题中包含了两个’to’字段,并且两者都应该写被保护,那么就应该在签名的’h’选项中包含’to’两次。

签名唯一的硬性要求就是必须包括’from’,除此之外,标准都是比较模糊的。在RFC 6376标准中5.4章中写道:

在选择哪些标题字段进行签名时给出的内容是不明显的,消息存在的签名字段如:Date, Subject, Reply-To, Sender, and all MIME这些头部。

有趣的是在5.4.1这一部分给出的例子中部分与声明相矛盾,因为一些新的内容被添加,那么另外一些规则就会被忽略。然而, opendkim正将5.4.1列表中的字段规定为推荐字段,不过这里面并不包含邮件内容类型以及内容传输编码等重要的字段。更奇怪的是,作为当前DKIM标准的RFC 6376的前身RFC 48771在5.5节中可以看到列表里面的内容比前者更多。

除了标注头字段表达不清楚之外,当前标准对于如何防止额外添加字段的描述更加模糊。在标准中明确表示额外添加字段会产生很严重的攻击。

破解DKIM的目的

DKIM标准的模糊性,缺乏安全默认值,以及MIME标准的实现的复杂性,灵活性都可以产生改变邮件的主要信息,比如主题,甚至改变整个邮件的内容。包括添加新的恶意附件。

欺骗邮件头部:Subject,Content-Type等等

我的研究表明头部签名是不够充分安全的,并且在许多情况下可能会存在DKIM绕过,达成钓鱼。虽然在邮件中我已经分析出在签名中97%是包括了邮件内容。3%是防止恶意增加主题标题。但是GMail和AOL网络邮件在有多个主题的情况下只会显示第一个主题行的内容,而DKIM签名仅涵盖最后一个主题行。这样一来攻击者就可以轻易的改变显示的主题,而不影响签名的有效性。
而且,当继续绕过Content-Type头部验证时,这也是可能实现的。

通过下面简单的一个邮件举个例子:

    DKIM-Signature: v=1; h=from:to:cc:subject:content-type; ...
    From: <[email protected]>
    To: [email protected]
    Subject: 20170920:1755 - good
    Content-type: multipart/mixed; boundary=foo
    Date: Wed, 20 Sep 2017 17:55:18 +0200

    --foo
    Content-type: text/plain

    some text
    --foo--

使用安装DKIM插件的邮件客户端Thunderbird查看邮件时显示如下:

thunderbird-good1.png

但是通过添加额外的Subject以及Content-Type头部,它显示的结果会发生不同:

    Subject: Urgent Update at http://foo
    Content-type: multipart/mixed; boundary=bar
    DKIM-Signature: v=1; h=from:to:cc:subject:content-type; ...
    From: <[email protected]>
    To: [email protected]
    Subject: 20170920:1755 - good
    Content-type: multipart/mixed; boundary=foo
    Date: Wed, 20 Sep 2017 17:55:18 +0200

    --foo
    Content-type: text/plain

    some text
    --foo--

我们可以观察到subject是不同的,并且邮件正文已经没有了,但是DKIM验证结果还是正确的。

欺骗邮件正文:攻击者完全控制正文内容

在特定的情况下,攻击者不仅可以控制Content-Type之类的头部,而且还可以控制邮件的正文,包括改变正文内容,或者添加附件。当然在添加的同时保证了DKIM的验证结果仍然有效。

如果邮件发送方在签名中使用了’l’选项,那么这种攻击就可以被实现。通常’l’属性是用于保护签名的有效性,即使邮件服务器或者防火墙在邮件正文末尾添加了它们各自的签名。比如“这一邮件已经通过xyz杀毒软件的扫描”类似的字段。

通常情况下,服务器设置的’l’值是覆盖的正文全部内容的。因此,可以推断出我们不能改变正文的内容,但是可以在正文最后添加一些东西。不过我在德国的一家大型企业中发现,不管他们发送的邮件长度为多少,他们的DKIM只是覆盖了邮件的前10个字符。这种错误的配置使得攻击变得更为简单。

作为一个例子,在2016年年初我们通过DHL.com发送了一个实际的邮件。因为没有添加DKIM签名到期时间,所以在2017年9月这一签名还是有效的。并且DHL也没有更改RSA加密的密钥。原始邮件在Gmail的web界面看起来如下图:

gmail-dhl-good.png

通过查看这一邮件的源代码,发现一些选项是被签名保护的,但是签名并没有防止添加另外字段。并且在签名中,一些重要的选项并没有包含其中。正文hash值仅仅涵盖了邮件的特定部分,所以在原始邮件正文中添加任何东西都不会使签名验证失效。

具体来说的话,我们可以在邮件中继续添加另外一个Date、To、Message-Id等等其他选项,并且可以更改当前的Content-Type、在正文中添加任意数据。这样都不会使签名无效。更改的内容为红色,原始邮件为黑色和蓝色:

1507271157944307.png

这里能够替换正文的原因是因为重新定义了具有不同MIME边界的Content-Type。在MIME边界之前的任何内容都被视为MIME的前导码,并且在任何兼容mime的邮件客户端中忽略。这就意味着在客户端显示的邮件内容是攻击者修改之后的内容,而不是原始的邮件内容。

gmail-dhl-bad.png

在”signed-by”字段中可以看到签名仍然有效。而且如果我们查看邮件的来源,Gmail会提供一个很好的摘要,其中包括攻击者设置的Date以及Messahe-Id.由于DKIM签名与显示的发件人DMARC的域相匹配,所以即使邮件未通过DHL的邮件服务器发送,也会成功:

gmail-dhl-src.png

这个问题的确很严重,我在过去的日子里发现,不仅是dhl.com在DKIM签名中使用了’l’选项,而且我在cisco.com,deutschepost.de或者dpdhl.com发送的邮件中都存在这一问题。有趣的是,DKIM标准的制作者已经发现了’l’属性的问题,在8.2章节

使用’l’标签可能会在邮件中显示欺诈内容,并且用户可能不会察觉到……这种攻击的一个例子包括改变MIME结构。……

为了避免这种攻击,进行签名的过程应该非常警惕使用这一标签。

打破DKIM

在之前我们已经展示了如何使用现有邮件创造欺诈邮件,并且DKIM不会失效。这就使得DKIM并不是那么可信赖的,即使DKIM签名有效,那也不能确定邮件是不是被修改过。

另外还有一个问题,由于SMTP协议的特殊性,即使邮件没有被改变,DKIM签名同样会失效。这就意味着尽管现在邮件已经被修改了,但是收件方同样可能会认为这一邮件没有问题。

传统的邮件只限于ASCII进行编码,行长度为1000个字符。MIME标准定义了Content-Transfer-Encoding的base64以及quotable-printable不限于传统邮件规定。但是这些编码效率不是很高,如果客户端可以忽略历史性限制,使用完整8位传输邮件,这样会好一点。

这里可以使用8BITMIME拓展进行邮件传输。如果邮件服务器支持此类拓展,那么客户端就会忽略只识别ASCII字符的规则。但是邮件的传递过程并不是点到点传递的,而是逐跳进行传递的。传递路径上的第一个服务器支持8BITMIME并且接受这样的邮件,但是路径上另一个邮件服务器不支持8BITMIME。在这种情况下邮件需要转换成仅ASCII格式。不过这样会破坏现有的DKIM签名:

no-8bitmime.png

这一问题在DKIM标准中也已经提到,并且说了如何解决这一问题:

在某些邮件中使用了8BITMIME,在传输过程中,会转换为7位格式,进而破坏DKIM签名。为了将破坏损失达到最小化,签名者应该在签名之前将邮件内容转换为合适的MIME内容传输编码。这种转换超过了DKIM的范围,在DKIM呈现之前,实际的消息被MUA或者MSA转换为7位MIME。

然而,几个主要的邮件服务商并没有注意到这一问题,因此在实际发送邮件的过程中会受到这一转换问题的影响。比如Paypal和Booking.com的邮件就受到了这一邮件的影响,尽管大部分邮件看起来很正常,但是由于主要的邮件服务商不支持8BITMEME,所以会受到这一问题的影响。

如何修复这一问题呢?

虽然DKIM标准试图将大部分验证工作都交给接收方,但是实际上作用并不大。相反,发送方和接收方都应该作出最大努力:发件人应该确保邮件无法在不破坏签名的情况下进行修改,收件人应该检查签名是否完好。这样邮件就不会被恶意修改。

在发送方,这意味着首先要确保邮件符合历史性限制,即全ASCII码,行长度最多为1000个字符。如果邮件不存在,则需要在进行DKIM签名前进行转换。

为了防止攻击者添加额外的标题,签名本身需要包含可能会影响邮件显示的所有邮件头。需要进行签名的标题很显然是从展示给用户的内容选出,比如:Subject,来自,发送到,日期,以及发送者。另外,应该包括影响消息显示的任何标题,即内容类型,内容传输编码,内容处理和MIME版本。而且还有一些标题会影响未来的消息流,或者是如何在其他人的上下文中显示这个消息,例如“回复”,“应答到”和“引用”。只要所有可能影响消息显示的头部都包含在签名中,那么将身体的长度添加到“l”属性也可能是有用的。

在接受方,应该检查每个相关的标题是否包含在签名中。不包括在签名中的任何标题都应该非常小心处理,并且在显示消息时不要过分信赖签名。鉴于这在许多情况下是不可能的,至少应该向用户传达DKIM签名不包括关键头部,即使签名看起来是有效的,因此可能会欺骗该消息。另外,如果设置了’l’属性,那么只有被限制的主体哈希所覆盖的部分才能显示给最终用户,否则散列外的部分应该被明确地显示为不可信。

当然,最好的是,如果所有发件人都使用S/MIME或PGP签名他们的消息,并且所有客户端都将检查此端到端签名。但这可能是未来几年的梦想,因此我们需要使SPF,DKIM和DMARC等当前的解决方案更加可靠。

总结

DKIM尝试通过发送MTA签署邮件来处理发件人欺骗。虽然这个想法在理论上是合理的,但标准过于灵活。它只提出模糊的建议,然后依靠具体的实施和配置来提供必要的安全性和可靠性。鉴于缺乏明确的要求,所以实际使用的DKIM在许多情况下都不能提供预期的效果。

源链接

Hacking more

...