“约翰,你被解雇了!”– 电子邮件中的OpenPGP和S/MIME签名欺骗
2019-09-02 14:44:33 Author: mp.weixin.qq.com(查看原文) 阅读量:54 收藏

笔记作者:CDra90n@SecQuan

原文作者:Jens Müller,Marcus Brinkmann,Damian Poddebniak, Hanno Böck,Sebastian Schinzel,Juraj Somorovsky,Jörg Schwenk

原文标题:“Johnny, you are fifired!” – Spoofifing OpenPGP and S/MIME Signatures in Emails

原文来源:USENIX2019

原文链接:https://www.usenix.org/conference/usenixsecurity19/presentation /muller

    OpenPGP和S / MIME是加密和数字签名电子邮件的两个主要标准,提供数字签名以保证消息的真实性和完整性。本文在五个攻击类中展示了针对OpenPGP和S/MIME电子邮件签名验证的各种实现的可用伪造攻击。

01

简  介

    随着阿帕网演变成互联网,电子邮件的使用也发生了变化。电子邮件现在被军方,政治家和记者用于商业环境中的敏感通信。虽然可以使用SPF,DKIM和DMARC等技术对发送SMTP服务器的域进行身份验证,但这些技术仅可用于缓解垃圾邮件和网络钓鱼攻击。然而这些技术并未扩展到验证发送人员,这对于提供消息真实性是必要的。

    两个相互竞争的电子邮件安全标准OpenPGP和S/MIME通过数字签名提供邮件的端到端真实性,自20世纪90年代末以来,许多电子邮件客户端都支持这种安全标准。数字签名提供了一种保证,即邮件是由特定的人(即认证与不可否认)编写的,并且从那时起它没有改变(即消息的完整性)。由于严重的可用性问题,采用率仍然较低,但这两种技术在行业或具有高风险角色中都占有很大的份额。一个例子:Debian(一个拥有1000多个成员的志愿者团体)依靠签名邮件的真实性来对项目负责人和提案的表决。由此引出问题:是否有可能伪造一封签名的电子邮件,即使是一个细心的用户,也无法将其与有效的电子邮件区分开来?

    电子邮件上下文中的签名验证是复杂的。例如,电子邮件可以由发件人以外的实体签名,也可以转发已签名的电子邮件(导致部分签名的邮件)。此外,签名是电子邮件的可选功能,因此通常不强制执行。最重要的是,验证结果必须提交给用户,这样就没有误解的空间。如果不这样做可能会导致签名欺骗攻击,如下图所示为Apple Mail中伪造的PGP签名的屏幕截图,基于包装PhilZimmermann发布的签名电子邮件。

 1、OpenPGP电子邮件签名

    Phil Zimmerman于1991年发明了PGP(优良保密协议),由于它的普及,PGP被IETF标准化为OpenPGP。最流行的实现是GnuPG,在电子邮件中使用OpenPGP有两种常见的方法。对于内联PGP,电子邮件正文直接包含OpenPGP数据。未使用MIME多标准,MIME类型为text/plain。对于PGP/MIME,电子邮件具有多部分/签名MIME结构,其中签名消息是第一部分,分离签名是第二部分。有些电子邮件客户端支持PGP,但大多数(特别是Thunderbird、Apple Mail和Outlook)需要一个插件,它在邮件客户端和PGP实现(如gnupg)之间提供一个中间层。

2、S/MIME电子邮件签名

    1999年,IETF发布了S/MIME(安全/多用途互联网邮件扩展)版本3,作为基于证书的密码学的MIME标准的扩展。S/MIME是安全电子邮件协议悠久历史的产物,可以看作是第一个基于互联网标准的数字签名、认证或加密电子邮件的框架。S/MIME使用加密消息语法(CMS)作为其基础容器格式。签名本身始终是CMS编码的,但是签名消息可以包含在CMS(不透明签名)中,也可以作为多部分/签名消息(分离签名)的第一部分传输。

02

攻击类别

    本文所述的攻击不会破坏数字签名中的加密技术,而是利用电子邮件客户端验证PGP和S/MIME签名的方式以及验证结果如何呈现给用户的弱点。

    定义了以下五个攻击类:

1、CMS攻击

    加密消息语法(CMS)是X.509公钥基础结构中签名和加密消息的通用标准。在处理具有矛盾或异常数据结构的电子邮件(如多个签名者)以及在X.509信任链中呈现问题时发现了缺陷。

2、GPG API攻击

    GnuPG是最广泛使用的OpenPGP实现,但它只提供一个非常有限的命令行接口来验证签名,此接口易受注入攻击。

3、MIME攻击

    电子邮件的主体在概念上是一个MIME树,但通常树只有一个签名叶。本文构造了非标准的MIME树,它欺骗客户端在验证另一部分中不相关的签名时显示未签名的文本。

4、ID攻击

    这个攻击类的目标是显示邮件头中受信任通信伙伴的身份(ID)的有效签名,尽管精心设计的电子邮件实际上是由攻击者签名的。

5、UI攻击

    电子邮件客户端通过在用户界面(UI)中显示一些安全指标来指示有效签名,例如带有印章的信函。但是,有几个客户端允许使用HTML、CSS和其他嵌入内容执行来模拟重要的UI元素。

    在场景中假设两个值得信赖的通信伙伴Alice和Bob,他们安全地交换了他们的公共PGP密钥或S/MIME证书。攻击者Eve的目标是创建一封任意内容的电子邮件,并将其发送给Bob,Bob的电子邮件客户端错误地指示电子邮件已由Alice进行数字签名。

    假设Eve能够创建任意电子邮件并将其发送给Bob。电子邮件的发送者被欺骗到Alice的地址,例如,通过欺骗FROM头,一种已知的模拟技术,应该通过数字签名加以阻止。这是默认的攻击者模型,前提条件最差。对于UI攻击类,以及一些CMS和GPG API攻击来说这已经足够了。

    对于MIME攻击类和某些CMS攻击,假设攻击者具有来自Alice的单个有效S/MIME或OpenPGP签名,该签名可能是从以前的电子邮件通信、公共邮件列表、签名软件包、签名的github提交或其他来源获得的。这也是一个薄弱的要求,因为数字签名通常不被保密。事实上在许多情况下,数字签名被明确地用于公开证明某些内容是由签名者创建的。

    对于 ID攻击和GPG API中的一个攻击,假设Bob信任Eve的签名。对于S/MIME,此条件始终保持不变,因为Eve可以轻松地从受信任的CA获取自己电子邮件地址的有效证书。对于OpenPGP,Bob必须导入Eve的公钥并将其标记为有效。这是一个更强有力的条件,但前提是Eve是Bob的合法通信伙伴。

03

攻击模型与方法

3.1 CMS攻击类

    加密消息语法(CMS,S/MIME使用的容器格式)是签名和加密电子邮件的通用标准。它不仅支持广泛的用例(例如,多个签名者),而且还可以处理遗留问题,例如缺乏软件支持和行为不当的网关。这使得标准更加复杂;CMS对象中的多个值是可选的,或者可能包含零个或多个值。此外定义了两种不同的签名格式。这使得开发人员很难测试所有可能的组合(可能可信或不可信)。

1、不透明和分离签名

    CMS和S/MIME标准定义了两种形式的签名消息:不透明签名和分离签名(也称为嵌入签名和外部签名)。签名始终是CMS对象,但相应的消息可以嵌入到该对象中,也可以通过其他方式传输。

    在不透明模式下签名时,待签名内容(即“消息文本”)通过所谓的eContent(或“嵌入内容”)字段嵌入到二进制CMS签名对象中(见下图)。

   上图为带有不透明签名的电文。消息嵌入到CMS对象中,人无法直接读取消息。

    在分离的签名中不存在电子内容,以表明内容将通过其他方式提供。这就是多部分/签名结构所做的;电子邮件分为两个MIME部分,第一部分是内容,第二部分是不带eContent字段的CMS签名(见下图)。

    上图为附有分离签名的讯息。消息位于第一个MIME部分,可由人直接读取。传统的软件往往会破坏这些电子邮件中的行尾或编码,从而破坏了签名验证。

2、eContent混淆(C1)

    即使使用了多部分/签名机制,当存在eContent字段时,也会出现混淆的情况。在这种情况下客户端可以选择要验证的两个内容(即不透明或分离的内容)中的哪一个,以及要显示的两个内容中的哪一个。显然,当验证的内容不等于显示的内容时,这是一个安全问题。

    “eContent混淆”可以完全地伪造任意签名的电子邮件给已经有签名的人。因为不透明的签名可以转换为分离签名,反之亦然,所以任何签名的电子邮件都可以用于攻击。

3、攻击细化

    尽管eContent没有显示在电子邮件客户端,但在取证分析中很容易发现旧电子邮件被重新用于此次攻击。有趣的是可以对攻击进行改进,以完全删除原始内容,而不影响签名验证的结果。与不透明和分离的签名类似,缺少的eContent表示在其他地方提供内容,CMS支持所谓的“签名属性”,其缺少或存在表示签名内容。如果存在signedAttrs字段,则签名将覆盖signedAttrs字段的确切字节序列,而不是内容本身。如果简单地实现,这当然会使内容未经身份验证。因此,signedAttrs字段必须包含哈希。如果缺少signedAttrs字段,则签名直接覆盖内容。

    这种间接签名允许用signedAttrs字段的确切字节序列替换原始内容,而不会影响签名验证结果。以这种方式修改的电子邮件将显示为“空”或包含看似“垃圾”(因为signedAttrs被解释为ASCII)。在这两种情况下,这都可以用来隐藏旧签名的来源。

4、多重签名者(C2)

    S/MIME和CMS允许多个签名者并行签署同一内容。显然,每个签名者的验证结果可能会有所不同,用户界面应该清楚地说明这一点。但是,显示简化版本是合理的。如果由于存在不相关的有效签名而将无效签名标记为“有效”,将其视为伪造。

5、无签名者(C3)

    CMS签名对象可以包含零个或多个签名者。尽管RFC5652对零签名者给出了有限的建议,但它没有明确地说明在没有签名者的情况下如何处理“签名消息”。

6、信任问题(C4)

    与OpenPGP不同,S/MIME是基于信任层次结构构建的。只要可以追溯到有效的根证书,证书就是真实的。实际上,这意味着大多数S/MIME证书(在InternetPKI中)都是间接信任的。但是,客户端必须检查证书链的有效性。如果客户接受无效的证书,例如自签名证书或其他不受信任或不一致的证书,认为这是伪造的。

3.2 GPG API攻击类

    GnuPG是一个独立的OpenPGP实现,它提供了一个基于文本的有状态命令行接口,大约有380个选项和命令。API的复杂性和使用者解析GnuPG的字符串消息的需求提供了丰富的攻击面。

1、GnuPG状态行

    GnuPG通过--status fd选项以简单的基于文本的格式(参见下图)发送状态行,从而提供了一个可读的计算机接口。每个状态行以[GnupG:]和大约100个可能的关键字(如GOODSIG)中的一个开始,然后是特定于关键字的附加文本。

尽管存在一些文档,但它并没有涵盖所有可能的状态行序列及其对任何给定操作的意义。事实上,由于流处理,API的复杂性反映了OpenPGP消息格式的总体复杂性。特别注意到以下风险因素:    

•API包含攻击者控制的文本(例如goodsig中的\<user-id>),必须对其进行转义以防止注入攻击。

•状态行的数量和顺序取决于OpenPGP包序列,该序列受攻击者控制。应用程序必须正确处理GnuPG允许的所有组合。

•API是有状态的,即状态行的语义取决于其在序列中的位置。例如,由TRUST_*线指示的有效性仅适用于由前一个NEWSIG启动的签名。

•使用API需要很好地理解GNUPG中实现的OpenPGP和信任模型。GOODSIG、VALIDSIG和TRUST_*行具有非常具体的技术含义,从接口中不一致的术语来看,这并不总是明显的。

•默认情况下,GnuPG在用户主目录的上下文中运行,使用其配置文件和密钥环,这可能影响GnuPG在状态行API内部和外部的输出。

    工作重点是注入攻击和应用程序解析接口。首先检查GnuPG的源代码,以确定攻击者可以在API中的受信任位置注入不受信任数据的位置。然后回顾所有开放源码邮件客户端,以确定API解析器中可利用的错误。

单个可信签名的示例输出(摘录)

GnuPG签名验证的重要状态行

2、带内注入攻击(G1)

    GnuPG状态行api中有许多地方在攻击者的控制下包含不受信任的数据。例如,GOODSIG状态行中的\<user-id>是一个来自公钥的任意字符串,攻击者可以使用该字符串来创建该公钥。一个简单的想法是在公钥的用户ID中附加一个换行符,后跟一个伪造的状态行。通常GnuPG通过正确地转义特殊字符来防止这种普通攻击。

    除了状态行API还查看注入攻击的日志消息。这是由于一种常见的模式,即使用gnupg的应用程序通过为两者指定相同的数据通道stdout(使用命令行选项--status fd 2)来合并状态API和日志消息。最优方法要求使用单独的通道,但技术限制可能会使某些插件和跨平台应用程序很难做到这一点。

    如果注入攻击成功,它可能非常强大,因为攻击者可以完全欺骗状态行并向应用程序提供任意数据。这种欺骗状态行可以包括对任意公钥成功进行签名验证的伪造指示。包含注入有效负载的有效PGP消息如下图所示。

通过日志消息注入GnuPG状态行的带内

3、使用GPG攻击电子邮件客户端(G2)

    GnuPG接口仅提供有限的功能;例如,不可能针对密钥环中的单个公钥验证签名,而只能针对其中包含的所有公钥验证签名。由于这不足以验证电子邮件的发件人,GnuPG返回一个包含用户ID和验证结果的字符串。通过操作此字符串,邮件客户端可能会被欺骗,从而提供错误的验证结果。

    使用GnuPG状态行API的应用程序必须解析状态行并指导状态机,在各种不同的输入、用户配置和GnuPG版本下跟踪验证和解密结果。因此,应用程序开发人员通常使用一个通用的设计模式来处理复杂性,例如:遍历所有状态行消息,解析那些具有与应用程序感兴趣的任务相关信息的状态行的详细信息,忽略所有其他未知或未知的支持的消息。这可能导致许多严重的漏洞。例如,如果应用程序没有准备好处理多个签名,它可能不会在NEWSIG状态行重置签名验证状态,将多个签名的验证结果合并为一个结果状态。这可能允许攻击者向现有消息添加更多签名以影响结果。另一个例子是使用未正确锚定到状态行API数据格式的正则表达式,从而允许攻击者注入数据,尽管GnuPG对其进行了正确的转义,但应用程序对其进行了错误的解释。

3.3 MIME攻击类

    在本节中将讨论在签名部分包装在多部分消息的MIME树中的情况下,电子邮件客户端如何处理部分签名的消息的攻击。对于此类攻击,攻击者已经拥有至少一条消息和要模拟的实体的相应有效签名。获得的消息可以是内联PGP、PGP/MIME或S/MIME,因为所有格式都可以作为多部分消息中的子部分嵌入。

1、预处理攻击者的文本(M1)

    即使只有一个MIME部分正确签名,电子邮件客户端也可能显示有效的签名验证状态。在这种部分签名的电子邮件场景中,攻击者可以混淆多部分电子邮件中正确签名的原始邮件的存在。例如,这可以通过将攻击者的消息预先发送到最初签名的部分来实现,用许多换行分隔,从而导致弱伪造。

2、使用HTML隐藏已签名的部分(M2)

    另一个选择是使用HTML和/或CSS完全隐藏原始部件,从而实现完全伪造。有几种方法可以做到这一点。一种方法是如果电子邮件客户端在向用户显示的单个HTML文档中呈现多个MIME部分的输出,那么签名部分可以简单地注释掉,例如使用HTML注释。此外它可以嵌入(因此隐藏在)HTML标记中,或者封装到诸如display:none之类的CSS属性中。下图显示了一个基于隐藏签名部分的MIME包装攻击的示例。

3、隐藏相关内容中的签名部分(M3)

    即使在多个MIME部分之间有严格的隔离,也可以使用cid:references(参见rfc 2392)来破坏它。这可以通过构造由两部分组成的多部分/相关消息来实现。第一个MIME部分包含一个由攻击者控制的文本和一个cid:对原始签名部分的引用,该部分放在第二个MIME部分中。下图给出了演示这种攻击的电子邮件示例。它包含一个HTML消息部分和一个签名文本,该文本由Phil Zimmermann于2001年编写和发布。cid:引用强制邮件客户端解析签名(但不可见)部分,该部分指示所示消息的有效签名(从第一部分)。这使得可以模仿Phil Zimmermann的任意信息。苹果邮件(GPG套件)的相应屏幕截图如第一个图所示。

4、在附件中隐藏签名部分(M4)

    即使不使用HTML,也可以通过将原始签名部分定义为附件来隐藏它。这可以通过将其放置到一个子部分中来完成,附加的标题行如下所示:Content-Disposition: attachment; filename=signature.asc

3.4 ID攻击类

    在本节中将讨论电子邮件客户端如何将签名邮件与发件人的身份匹配的攻击。这些攻击不如之前讨论的攻击强大,因为在用户交互的所有级别上都很少提供不可区分性,即许多客户端允许用户检查签名细节,这可能会显示攻击的迹象。

1、如果发件人=签名者则不检查(I1)

    在处理数字签名时,由谁签名的问题很重要。如果Bob的电子邮件客户端只显示任何PGP或S/MIME签名邮件的“有效签名”,那么Eve可以在其邮件上签名,并以Alice设置为发件人,将其发送给Bob。这是由于签名中的用户ID和FROM头中给定的地址之间缺少绑定。

2、显示名称显示为签名者(I2)

    有两个选项可以处理这个问题。首先邮件客户端可以在用户界面的某个地方显式地显示签名者的标识,并让用户将其与发送者地址进行比较。其次,电子邮件客户端可以检查签名者的身份(即电子邮件地址)是否等于发件人的地址,如果不是这样,则显示警告。第二个选项为攻击提供了很大的空间;对于S/MIME签名邮件,RFC2632指出“接收代理必须检查邮件消息的发件人或发件人头中的地址是否与签名者证书中的网络邮件地址匹配”。但是,实际上电子邮件客户端只能检查“发件人”头是否包含签名者的电子邮件地址,因为RFC 5322允许将其他显示名称与邮箱关联(例如,name<foo@bar>)。如果一个电子邮件客户端只向用户显示显示名称,那么Eve可以简单地将Alice设置为她自己的发送者地址的显示名称,参见下图a。  此外,在这种情况下,显示名称本身可以设置为向用户显示的电子邮件地址如[email protected],请参见下图b。

    下图a给出了一个Outlook屏幕截图示例。该邮件的源代码可以在下图b中找到。虽然Outlook总是显示完整的发件人地址([email protected]),但只需在显示名称添加大量空格即可“将其从显示中推出”([email protected])。

    图a Outlook中伪造的PGP签名消息的截图,该消息实际上是由攻击者签名的([email protected])

图b 伪造PGP签名的电子邮件源代码POC

3、收/发件人头混淆(I3)

    另一个问题是电子邮件客户端如何处理邮件头中的多个发件人字段,特别是如果PGP或S/MIME支持不是由电子邮件客户端直接实现的,而是通过第三方插件提供的,因为如何获取邮件头的发件人地址可能有不同的实现。例如电子邮件客户端可以显示第一个from头中给出的电子邮件地址,而插件将针对出现的任何头字段执行检查。此外该插件还可以在其检查中维护SENDER头,该检查“指定负责实际传输消息”的代理的邮箱,而邮件客户端将显示从“发件人”电子邮件头获取的电子邮件地址。请注意如果Eve设置了一个额外的回复:[email protected] 头,指示电子邮件客户端回复Alice,那么Bob在回复电子邮件时不会注意到此类攻击。但是,在大多数客户端中可以通过查看签名细节并将Eve定位为真正的签名者来检测它们。

3.5 UI攻击类(U1)

    在本节中将讨论利用向用户呈现签名验证结果的界面伪造攻击。如果伪造的消息与具有真正有效签名的消息不可区分,则攻击成功。

    此攻击类利用各种电子邮件客户端在电子邮件内容本身中显示签名的状态。用户界面的这一部分由攻击者控制。使用HTML、css或内联图像,很容易再现显示“有效签名”的安全关键用户界面元素。

下图c显示了Roundcube中的签名和伪造电子邮件。伪造的电子邮件基于使用HTML和CSS显示有效的签名标记(一个UI刷新的示例)。HTML代码如图d所示。

图c 两封电子邮件,其签名标记在视觉上难以区分。一个是PGP签名,另一个是巧尽心思构建的HTML电子邮件

图d 在RoundCube中伪造PGP签名,并进行用户界面伪装

04

结    论

    结果表明电子邮件签名检查和正确地将结果传达给用户是非常困难的,目前大多数客户端无法承受严格的安全分析。虽然这些攻击都没有直接针对OpenPGP或S/MIME标准或底层的密码原语,但它们引起了对电子邮件应用程序实际安全性的关注,并表明在处理应用的密码时,即使密码系统本身被认为是安全的,也会需要检查并仔细分析整个系统的漏洞。针对这些漏洞实施对策非常具有挑战性,因此建议OpenPGP、MIME和S/MIME为将来开发安全应用程序提供更具体的实施建议和安全最佳实践。

关于安全学术圈, 有兴趣加入学术圈的请联系[email protected]


文章来源: http://mp.weixin.qq.com/s?__biz=MzU5MTM5MTQ2MA==&amp;mid=2247484547&amp;idx=1&amp;sn=385c8fb5d906b17300af5e7d94ca8e35&amp;chksm=fe2efb08c959721e712a82add373ecc949b3263df178dea9b13770352f63344efeb88359647a#rd
如有侵权请联系:admin#unsafe.sh