RSS Feed
更好更安全的互联网
  • 分析 Curl-P 以及攻击 IOTA 加密货币

    2019-08-21

    作者:Ethan Heilman, Neha Narula, Garrett Tanzer, James Lovejoy, Michael Colavita, Madars Virza, and Tadge Dryja 
    原文:Cryptanalysis of Curl-P and Other Attacks on the IOTA Cryptocurrency 
    译者:知道创宇404实验室

    摘要

    本文介绍了使用伪造签名攻击IOTA区块链的方法。加密哈希函数Curl-P-27中存在一些弱点,允许攻击者快速生成可碰撞的短消息,并且这个方法也适用于相同长度的消息,利用这些弱点我们实现了对加密哈希函数Curl-P-27的攻击,破解了前IOTA签名方案(ISS)的EU-CMA。本文最后我们将介绍如何在消息已经被签署的情况下伪造有效支出的签名和多重签名(在IOTA中称为bundle)。

    关键词:加密货币,签名伪造,加密哈希函数,密码分析

    1 介绍

    加密货币通过数字签名来鉴别用户的转账行为。为了提高性能,在许多签名方案中,用户签署的是消息的哈希值而不是消息本身。在此情况下,如果底层哈希函数受到了攻击,攻击者便可以在付款时伪造数字签名。

    IOTA 的付款操作需要获得签名方案的授权。本文介绍了对该签名方案的攻击,这些攻击利用了哈希函数Curl-P-27的弱点。重要的是,我们在2017年8月披露并修补了此漏洞,由此保证了IOTA签名方案的安全性[20]。

    IOTA是一种加密货币,被应用于物联网(IoT)和汽车生态系统。截至2018年7月24日,它以26亿美元的市值成为全球第九大最有价值的加密货币[9]。许多公司与 IOTA 有过合作,包括汽车制造商大众汽车公司和欧洲大型工业公司博世公司。 IOTA 曾发布公告称大众汽车计划在2019年初发布一款使用 IOTA 的产品[7]。 2017年底,博世购买了“大量 IOTA代币”[6]。此外,IOTA 基金会与台北市签署了一项协议,将 IOTA 用于其智能城市计划,其中包括数字市民卡项目[8]。

    IOTA使用加密签名来授权用户付款。基于 Winternitz 一次性签名[25],IOTA建立了自己的签名方案(ISS)。但与传统的 Winternitz 签名不同,IOTA 用户签署的是消息的哈希值。由此可见,ISS的安全性依赖于其加密哈希函数,即 Curl-P-27。通过常见的差分密码分析方法,我们可以使用Curl-P-27快速创建哈希值相同且长度相同的消息,从而打破了功能的碰撞阻力。我们做到了每次都能在一个上限值之内实现碰撞。

    使用此碰撞攻击,我们可以在 IOTA 中伪造签名。我们从被签署的消息着手,为攻击者分别创建良性支付和恶意支付,并且使这两种支付具有相同的有效签名。我们的攻击适用于正常付款和多签名付款,并且只针对IOTA 签名方案,而没有包括整个 IOTA 网络。从多签名地址支出需要一个用户为另一个用户签名支付,这完全取决于如何设置被签署消息。我们详细介绍了如何攻击多签名地址支出,并提供了在单签名和多签名付款中生成碰撞的工具,并且评估了攻击的效率。在使用80个核的条件下,我们可以在不到20秒的时间内制造 IOTA 付款碰撞。

    1.1 漏洞状况和影响

    2017年7月14日,我们与 IOTA 开发人员准备披露这个攻击,并且就修补漏洞的时间安排以及发布日期进行了协商。 2017年8月7日,IOTA 开发人员部署了一个向后兼容的升级,通过将 Curl-P-27 替换为另一个哈希函数来消除漏洞[32]。为了进行升级,Bitfinex 暂停了其存取款业务,时间接近三天 [4]。所有直接持有 IOTA(不通过交易所)的用户都被鼓励升级他们的钱包和地址。 2017年9月7日,我们发布了漏洞报告[20],描述了此攻击的原理。

    在报告中,我们给出了有效碰撞和签名伪造的示例以及验证他们的软件。在此基础上,本文详细分析了破解 Curl-P-27 抗碰撞性的方法,并介绍了开发伪造签名的软件的流程。我们还研发了应对多签名方案的技术——选择消息攻击特别适用于多签名方案。我们没有向 IOTA 发送任何伪造签名或以任何方式攻击 IOTA。由于 Curl-P-27 不再用于 ISS,本文提出的签名伪造不适用于当前的 IOTA,同样不适用的还包括 5.2 节提到的的多重签名攻击。 Curl-P-27 仍然用于 IOTA 的其他部分[14],但我们不会对他们进行攻击。

    2 相关工作

    在我们发布了初始报告之后,Colavita和Tanzer [10]分别复现了我们的分析,并验证了Curl-P 的round函数,即这个函数通过排列的方法,根据特定的表达式进行舍入。他们二人也参与了本论文的撰写。

    1991年,Biham 和 Shamir [3]首次发布了差分密码分析技术(IBM的研究人员在1974年发现了类似技术但没有对外公布[11])。在本篇论文中,我们通过平衡三元加密哈希函数实现了差分密码分析的一个简单应用。除了我们的漏洞报告[10]以外,还有其他研究对基于三元的加密伪随机序列发生器进行了设计分析[16],但是没有研究过此函数的差分密码。

    通过对 Curl-P-27 的加密分析,我们对 ISS 的不可伪造性进行了选择消息攻击。或许我们还看不出降低碰撞抵抗性和建立攻击模型有多大的作用,但 MD5 哈希函数的研究过程可以给我们答案。王小云在 2004 年首次实现了 MD5 哈希算法的碰撞[35],并在随后发布了生成随机碰撞的通用程序[34]。 2005年,Lenstra 与王小云合作将这个加密漏洞应用于X.509 认证中。X.509 支持 HTTPS 等协议,并且能够构建成对的碰撞证书[24],是公钥基础设施的基石。有人认为证书颁发机构不会签署此类可疑证书,而且由于 X.509 认证缺乏“有意义的”结构,它很有可能被滥用。2007 年, Stevens 加入 Lenstra 等人,将 MD5 的原始随机碰撞攻击扩展到选择前缀碰撞攻击[30]。2009年,Stevens 等人宣布他们已经成功伪造了一个 X.509 证书,其拥有的证书权限能够通过所有主流浏览器的验证 [31] ,导致供应商立即废弃 MD5。

    之后,IOTA 开发人员替换了 IOTA 签名方案中的哈希函数, Curl-P-27变成了基于 Keccak 的 Kerl。2017年10月,他们发现了一个名为13攻击(也叫 M 攻击)的无关漏洞[23]。对于哈希值在[-13,13]区间内的消息,数字13的签名(又记作“M”)显示明文是私钥的衍生物,并可以被用于伪造所有的后续消息块,由此造成漏洞。为解决此问题,IOTA 基金会要求用户必须更改消息,直到摘要中没有 13。另一种补救措施是,开发人员将可能受到损害的资金转移到其他地址,用户之后可以通过向基金会提出申请,并收回其资金[27]。

    3背景

    在本节中,为了读者能更好地了解这个攻击,让我们首先简要回顾一下 IOTA 的一些不常见的设计特性和术语。我们还会对 Curl-P 哈希函数和IOTA 签名方案(ISS)进行概述。

    3.1 IOTA设计

    IOTA 有一些特别之处。首先,IOTA 使用平衡三进制而不是二进制;第二,IOTA 的付款被称为bundle;第三,IOTA 使用一种称为 tangle 的新数据结构而不是传统的块链;第四,IOTA 聘请一个称为协调员的可信方来检查状态并批准付款。

    IOTA 的数据结构使用平衡三进制而不是二进制,其中用于计数的符码为{-1,0,1},一个三进制字节由三位符码组成,每个字节代表了 [-13,13] 的整数。 IOTA经常将三进制字节序列化为字母A-Z和数字9。

    IOTA 内的付款方式用一种叫做 bundle 的数据结构来表示。Bundle 由多个交易组成,但 IOTA 交易与其他加密货币交易不同,它们是负责存储输入或输出的缓存,除此之外还有地址,签名,价值和标记等字段。在第 5 节中对这个攻击进行描述时,我们也会详细描述 IOTA 的 bundle 和交易格式。

    IOTA 是基于 tangle 的概念建立的[26],其类似于DAG链,其中每个块可以引用多个块父[29]。然而,在 IOTA 中,没有块可以汇总多笔付款。相反,每个交易必须有一个 nonce 以用于 PoW,还需要含有指向其他两个交易的指针。为了将交易添加到 tangle 中,用户从 tangle 中选择两个小费以在其交易中引用。一旦创建并且得到签名,用户就会有足够的工作证明,并将交易(或bundle的情况下的交易)广播到IOTA网络。

    在目前部署的IOTA中,bundle只能在获得协调员的批准之后才可以被接收。协调员是由IOTA开发人员运营的可信方,检查和批准tangle的状态,并对tangle签名。人们担心IOTA是集成的,或者受到IOTA开发人员的控制 [33]。 IOTA开发人员称IOTA不是集成的,协调员是一种临时措施,且IOTA没有公开其源代码。由于我们没有与IOTA沟通,我们无法确定协调员将如何影响我们发起的攻击,但是据我们所知,协调员没有机制可以防止本文提到的攻击。

    3.2 IOTA的签名方案(ISS)

    受到Winternitz一次性签名(W-OTS)的启发,IOTA使用了类似的签名方案[25]。 W-OTS对Lamport签名进行了优化 [22],同时操作多位,不惜计算成本来缩短公钥长度。

    ISS与W-OTS有很多不同。首先,与传统的W-OTS一样,ISS操作的是消息的哈希值,而不是像 W-OTS那样直接在消息上进行操作。其次,ISS没有使用校验和,而是对消息的哈希值进行规范化。

    ISS有三个安全级别。安全级别1仅签署消息的哈希值的三分之一,安全级别1签署前三分之二,安全级别3签署整个哈希值。因为我们的攻击是针对最高安全级别的,所以它也应当适用于其他所有安全级别。因此,当下文涉及到ISS时,我们将默认其使用了安全级别3。

    3.3 Curl-P

    在本节中,我们将描述Curl-P哈希函数。 Curl-P(有时称为Curl)是一种加密哈希函数,被用于设计IOTA。 它的用途包括创建交易地址、消息摘要,工作证明(PoW)和基于哈希的签名。 在高层次上,Curl-P遵循海绵结构模式[2,18],但在一些关键位置上有变化。 由于IOTA项目尚未提供任何官方规范说明或分析,我们对Curl-P的开源部分进行说明。

    与大多数加密哈希函数不同,Curl-P使用的是平衡三进制。为表达清楚,我们用小写字母表示单个三进制符码,例如a; b; c; x; y; z, 再用大写字母表示连续的三进制符码,如S; N; X; Y。使用下标符号表示一个序列中的单个字符,例如Si。遵循IOTA惯例,Curl-P-R中的R表示轮次(例如,Curl-P-27表示27轮Curl-P)。

    Curl-P运行过程如图一所示:(1)Curl-P的初始化状态S是一个长度为729的全零三进制序列。 (2)消息被分成消息块mb0 · · · mbn,每块长度为243。 Curl-P不使用消息填充,如果一条消息的长度不是243的倍数,允许最后一个消息块小于243。4(3)每个消息块mb0 · · · mbn依次被复制到状态S的前三分之一,并由函数f r进行转换。 (4)当没有消息块之后,Curl-P返回最终状态的前三分之一。有关更详细的描述,请参阅算法1。

    现在来看负责转换状态S的函数fr 。转换函数fr 就是将f函数递归调用r次,例如f 3(S) = f (f (f (S)))。 Curl-P-27就是Curl-P哈希函数,其变换函数是f27

    调用一次fr 就能获得S的新状态。 如算法2中所述,初始状态中的每相邻两位符码通过简单函数g的转换,变成新状态中的一位数字。 当前状态中的每一位都会被使用两次,一次作为g的第一个参数(由a表示),一次作为g的第二个参数(由b表示)。 在表1中,我们给出g作为替换表(s-box)。

    !

    4 Curl-P的密码分析

    在本节中,我们应用常见的差分密码分析法来构造完全碰撞。我们构造两条相同长度的消息,设置他们只有一个符码不同,而且他们通过 Curl-P-27 会映射到相同的值。我们可以控制碰撞消息的内容,包括任意消息前缀和后缀。在下一节中,我们将利用他们来伪造有效IOTA支付的签名。

    除了IOTA开源项目发布的一部分源代码,我们无法找到 Curl-P 或 Curl-P-27 的正式规范文档。此外,IOTA开发人员表示,Curl-P-27 旨在对特定的输入组[5]进行碰撞。事实上,Curl-P-27 是非随机的。正如[10]中详细探讨的那样,可以在相同长度的消息中观察到 Curl-P-27 的非随机行为;碰撞和第二个预成像对于生成不同长度的消息是微不足道的。因此,为了确保我们真正破解了 Curl-P-27,我们表明我们的碰撞攻击破坏了 Curl-P-27 的安全属性(参见第5节)。

    在高层次上,我们的攻击工作如下所示。我们选择两条长度至少为三个消息块的消息,并且他们只有一位符码不同。为了降低困难,我们使这两条消息满足某些约束方程(在第 4.2 节中详细说明)。一旦我们进入包含不同符码的消息块,我们就需要确保会发生碰撞。为此,我们在两个消息中随机翻转一组三进制数,并且每组不能超出其所在的消息块。我们的思路是对两条消息做变换处理,并且使不同的那一位在转换完成后处于结果状态的前三分之一的位置。

    27(S)[243,729] = f27(S‘)[243,729]

    因为Curl-P用下一个消息块替换了S的前三分之一,这导致原本的差异被覆盖,造成完全碰撞。我们利用Curl-P-27的不同特性多次强制转换函数,这样的话,在最后一轮时这些差异可能还保持在状态的前三分之一。经过多轮转换之后还保持着一位差异,找到这样的两条消息需要调用Curl-P-27次数的上限是760 万次或 22287次。

    在图2中,我们可以看到在Curl-P-27中,不同的轮数会导致不同的结果。我们用颜色代表发生碰撞的可能性,x轴表示差异点的位置,y轴表示在该轮数内差异没有扩散。我们对每个位置和深度执行100个样本(总共11 243 100 = 267300个样本),每个样品随机初始化,差异点的内容设置也是随机的。更多数学分析请参阅[10]中的复现。

    我们设置差异符码出现在第 17 位。根据实验结果,知道了轮次和差异点的位置,我们可以计算碰撞的概率。在此条件下递归20次后,碰撞的概率是1.0。因此,只要我们保证差异不会扩散,我们就可以制造碰撞。这种攻击应该同样适用于输入的消息块中的其他位置(如[10]所示)。请注意,这是确保发生碰撞的上限,因为递归次数少于20次时也可能发生碰撞。

    4.1 Curl-P变换函数f r的不同性质

    在本节中,我们将展示如何找到目标状态,将差异保持至少20轮。这需要我们分析Curl-P变换函数f的不同性质。

    差分密码分析涉及研究两组及两组以上的输入之间的差异传播模式。最常见的技术是寻找差异轨迹。差异轨迹是一组概率偏差,表示一组差异如何通过多轮加密函数传播到另一组差异。这里我们只使用特定的差异轨迹,即在转换函数f的重复应用下,两个状态S,S‘之间的某一位的差异。我们证明了 Curl-P 强烈偏向于保持一轮的单符码差异(即f的应用)。

    首先介绍其中涉及的术语。由于Curl-P使用三进制符码∈{?1,0,1},我们必须使用新的三元符号表示法。为了表示两个符码 x 和 x' 之间的差异,我们使用Θ ( 0Θ ?1 代表 x = 0 ,x’ = ?1 或者 x = ?1 , x‘ = 0)。通过术语扩散,我们指出在调用f之后,两个状态之间的差异的数量已经增加(即,差异已被使用)。

    我们的攻击是围绕着一个事实,即s-box g不会一直传播差异。例如,考虑g的两组输入和输出:g: a,b,c and a‘, b’, c‘ such that g( a, b ) = c and g( a', b' ) = c'。我们做出以下观察:

    1.对于所有可能的值,如果 a ≠ a' 且 b = b',那么 c ≠ c' 。

    2.如果a = a' 且 b ≠ b',则可能有 c = c' 或 c≠c'(例如,a = a'= 1,b = 0且b' = 1,则c = c' = 0)。

    每调用一次 f 就是更新一次状态。如3.3节所述,g 中每两位符码经过转换以后变成新状态中的一位符码。先前状态的每一位最多被转换两次:一次作为第一个变量a,一次作为第二个变量b。这意味着单位符码差异将延续到下一轮,因为当它是s-box g的第一个变量a时,g的输出将与a不同(如图1所示)。因此,如果将f应用于两个状态S,S',更新后的状态f(S),f(S')将始终有一位或两位的不同,不会出现无符码差异。

    我们模拟了状态在k轮Curl-P后保持单位符码差异的概率。 如图3所示,此马尔可夫模型列举出了所有可能的输入与其转换后的结果。 例如,如果当前的差异为 0Θ1,那么它有 1/9 的概率在下一轮中保持不变(即0 1),2/9 的概率变为 -1Θ0,或者有 6/9 的概率使差异个数从1增加到2(标记为失败状态,因为它未能保持单符码差异)。

    顶行表示 0Θ1 的转换到各个结果的概率,第二行是 -1Θ0,第三行 -1Θ1,第四行是差异由一位变为两位。使用这个矩阵,我们计算了在调用 k 次 f 之后差异保持一位的概率的下界,因为我们没有计算差异位数超过 1 位之后再变回1位的情况,所以这是一个下限。

    因此,从 0Θ1 开始,通过将矩阵提高到我们希望的轮数并计算概率。例如我们将矩阵幂 3 次,那么得到的矩阵中的数字就是符码在转换 3 次以后变成对应新符码的概率。因此,我们可以测量k轮后也不失败的概率。

    之前,我们通过实验验证了,如果经过 20 轮 Curl-P-27(即调用20次f)转换仍保持单符码差异,那么碰撞的概率是1.0。使用我们的状态转移矩阵,我们计算20轮,我们的攻击有一个每个查询成功概率下限为 2-42。也就是说,我们需要尝试242次才有可能找到将差异保持到20轮以后的消息对,这样的消息对可以产生碰撞。在下一节中,我们将展示如何显着减少对 Curl-P-27 的必要查询次数。

    4.2差分求解

    在本节中,我们将展示如何通过选择具有特定属性的消息来减少 Curl-P-27 的查询次数。我们首先展示如何约束有一位差异符码的状态 S 和 S‘,使得他们需要至少9次递归才能保持一位的差异(即差异没有扩散)。为此,我们将f表示为方程组,并求解状态S和S’中的特定值。

    我们可以将变换函数f r(S) 表示为一系列方程。例如,调用一次 f 可以写为

    f (S)0 = g(S0,S364),f (S)1 = g(S364,S728),...,f (S)728 = g(S365,S0)

    其中f (S)0是调用f后获得的新状态的第0位的数字。由于每一轮只是f的递归应用,我们可以根据状态S的初始值在f轮后写出特定位的值。我们使用上标来表示轮次。例如,用

    2(S)6 = g(g(S366,S1),g(S184,S548))

    表示在位置6进行两次递归运算。

    使用这种表示,我们找到可以使得 0Θ1 的差异保持9轮的方程。然后我们找到满足这些方程的消息前缀。 目前,我们可以在一秒之内查找到此消息前缀(有关我们的性能评估,请参见第 5.3 节)。 另外,给定一个特定的消息模板,我们只需要在两个消息块中更改一小组三进制位,便可以将其转换为令人满意的消息。

    4.3 寻找碰撞

    攻击需要至少3个信息块:mba, mbb, 和 mbc。其中mbb含有一个差异符码。mba前面的消息块数量没有限制,mba和mbb之间也没有,mbc总是跟在mbb之后并且重写mbb在前三分之一制造的差异。mbc的取值不会对攻击造成影响,可以取任意值。

    完整的攻击过程如下。首先,在我们攻击的约束阶段,我们通过调整mba和mbb来找到合适的消息前缀,这样它们可以保证 9 轮的单位符码差异。 接下来,在蛮力阶段,我们在mbb中的特定位置随机改变符码,目的是找到两个消息,使得从位置 17 开始的差异保持 20 轮。 由于约束阶段确保蛮力阶段的每次尝试在 9 轮中保持单符码差异不同,因此蛮力阶段的攻击复杂性从 20 轮减少到 11 轮。 结果,每个查询的成功率的下限减少到大约2 -22.87或 760 万分之一。

    正如差分密码所分析的,我们的概率计算简化了假设,即输入值是均匀随机的。考虑到 Curl-P-27 的低扩散率和Curl-P 的非随机性,这种假设可能不会总是成立。 但是,如第 5.3 节所示,本节给出的界限与实际结果相当接近。

    5 利用Curl-P中的碰撞来伪造签名

    本节中,我们将使用Curl-P-27碰撞对IOTA签名方案(ISS)执行签名伪造攻击。结合上一节的内容,我们将展示如何创建两个有效的IOTA bundle(即支付),这两个bundle最多只有两位不同,并且他们具有相同的Curl-P-27哈希值。然后,我们将描述攻击的设置,利用这些碰撞的 bundle 来伪造签名。最后,我们将展示如何攻击ISS多重签名。

    5.1 对ISS的选择消息攻击

    我们的攻击是一种选择消息攻击,恶意用户 Eve 欺骗用户Alice,先是要求Alice签署b1,然后根据b1生成相应的b2,这个b2也能通过验证。具体过程如下:

    1. Alice生成密钥对(PK, SK)。
    2. Eve通过碰撞攻击产生两个bundle b1,b2,并使得 b1 ≠ b2 且 CurlHash(b1)= CurlHash(b2)。
    3. Eve将b1发送给Alice并要求Alice签名。Alice检查b1,确认它是安全的。
    4. Alice在夏娃上给b1签名,即Sign(SK, b1)→ σ。
    5. Eve产生一个bundle对(σ,b2),使得 b1≠b2,b2是一个有效的 bundle,就算 Alice从未见过b2,b2也能够通过Alice的公钥验证。

    在4.3节中,我们介绍了攻击的一般格式,它至少需要三个消息块 mba,mbb和mbc。 为了执行攻击的第一阶段,我们将 mba 和 mbb 中的某些特性设置为特定值。 在暴力阶段,我们每次尝试更改 mbb 中的其他符码并检查我们是否已经实现了碰撞。 但是,bundle必须通过 IOTA 软件中的有效性检查才能被 IOTA 视作有效bundle,这限制了我们可以修改的位数。

    要想计算 bundle 的哈希,需要对每个交易的地址,值,标记,时间戳,当前字节和最后字节的串联结果计算哈希值。交易的格式如图4所示。大多数字段的格式都有严格的规范格式。例如,bundle 中值的求和结果不能为负,时间戳必须在一定范围内,并且索引必须与 bundle 中的交易对齐。标签不会影响 bundle 的语义或有效性,并且可以包含任意的符码。因此,对于约束阶段和暴力阶段中的每次尝试,我们只更改 tag 中的符码。

    另一个重要的问题是要在哪里生成碰撞。在最初的漏洞报告中,我们展示了两种不同攻击方式的碰撞 bundle:一种将碰撞置于地址范围内,使得 Alice 无意中签署了一项交易,该交易将取走 Eve 的资金,Eve 可以声明 Alice 犯了一个错误。第二次将两个碰撞放在一个 bundle 中的两个地方,导致 Alice 无意中签署了一个交易,该交易比预期更多地支付 Eve。在下一节中,我们将详细描述需要多个签名的 bundle 的后一种攻击方式,这些签名是我们选择的消息设置。

    5.2 多重签名攻击

    我们在漏洞报告[20]中伪造的攻击是选择消息攻击,也就是说,Eve必须要求Alice签署bundle。为了证明保障被签署消息的安全性有多么重要,我们现在将攻击扩展到 IOTA 多重签名方案[28]。在多重签名中,只有在多方签名以后才可以支出资金。为了达到这个目的,一方创建一个bundle并要求另一方签名,这便是选择消息攻击。 IOTA基金会鼓励部署热存储/冷藏解决方案5,以达到使用多重签名来安全存储资金[12]的目的。多重签名迫使攻击者必须使多方妥协,这是它被使用在加密货币环境中的一个主要原因。我们的攻击恰好消除了多重签名的这种安全优势。我们将考虑一个2-of-2 的简单案例,其中两方都签署了花费资金。这个攻击还会推广到更复杂的设置。

    考虑 Eve 和 Alice 各持一对 ISS 密钥:(PKE, SKE)和(PKA,SKA),只有Eve的密钥签名和Alice的密钥签名同时存在才能取出资金。这意味着Eve和Alice之前已经进入了 2-of-2 的多重签名,并且现在正共同使用这笔资金。我们的攻击将做如下工作:Eve将计算两个相互碰撞的bundle,一个向Alice支付资金,另一个向Eve支付资金。 Eve将签署并发送bundle给Alice,这个bundle负责向Alice支付资金。一旦Eve拥有 Alice 的签名,她就会在创建一个Alice从未见过或未授权的有效bundle,并且广播这个bundle.6。在此设置中,Eve要么是恶意的,要么已被恶意方攻击。

    为了构造这样的bundle,Eve将碰撞置于某个碰撞的某个value字段。图5显示了bundle的前四个消息块。突出显示的字段与攻击相关。通过在碰撞前后操纵标记字段中的特征,Eve导致第二交易(消息块3)中的value字段的第17位发生碰撞。这样,Eve可以在第二个交易中生成两个不同的bundle,这些值具有相同的哈希值。 Eve随后在第四个交易(消息块7)中生成了第二个碰撞,这次使两个bundle的值仍然总和为零。这用于设置向谁支付多少金额。

    为了生成这些碰撞,一般需要我们按顺序进行两次攻击。在我们当前的碰撞工具中,我们在两个交易之间还需要一个交易。满足了这个要求,以及冲突不在第一个或最后一个交易中的要求,我们就可以处理具有不同数量的交易的bundle。我们的工具只能在消息块的第17位中产生碰撞,不过这是工具的限制,而不是因为第 4 节中的密码分析有误。我们的工具在生成碰撞时不依赖于交易中特定的地址和值,但是必须保证对应位的符码不同才能产生有效的bundle。例如,如果在 b1 中 Alice 和 Eve 的输出值的 17 位为零,那么在b2中将Eve的输出值的17位变为1会导致b2的总和不为0。在 b1 中,Alice 的输出值的第 17 位应为1,Eve的应为零。

    在附录B中,我们展示了使用此技术创建的两个示例bundle。其中bundle为支出500,000,000 IOTA货币,由Alice和Eve控制。Alice丽丝签了一个bundle,它支付Eve 1 IOTA,其余的支付给其他地址。在碰撞的bundle中,Eve收到 129,140,164 IOTA货币,支出地址为Alice的地址。

    碰撞单签名bundle的生成方式与此类似。我们在漏洞报告中伪造了bundle的签名,其向三个地址进行支付。在良性bundle b1中,Alice在她控制的两个地址收到 50,000 和 810,021,667 IOTA 货币并向Eve支付100 IOTA货币。在恶意bundle b2 中, Eve进行了调整并且收到了 129,140,263 IOTA货币,这些是Alice的钱。我们还没有研究在value和address字段之外制造碰撞会带来哪些影响,可能会生成其他攻击。

    5.3 性能分析

    我们在 64 位Linux 4.9.74 环境下,使用一台配备了 8 个 2.4GHz 10 核 Intel 芯片和 256 GB RAM 的 Intel 机器运行此攻击。 我们的攻击占用了全部的 CPU,但占用的 RAM 空间可以忽略不计。 如第 4.3 节所述,碰撞包括两个阶段:约束阶段计算约束集,而暴力阶段在 tag 中产生随机数以产生碰撞。

    约束阶段生成并求解十八个等式,前九轮 Curl-P-27 中的每一个都有两个。 约束阶段在 Python 中实现,并且是单核运行。 我们没有尝试优化第一阶段。 表2 显示了取第 17 位不同并且在第一阶段运行 5000 次后所需要的平均,最小和最大时间。

    表2 还显示了强力阶段的测试结果。该阶段使用第一阶段的符码和模板来强制生成碰撞。因为这在 Go 中执行并且并行,因此我们需要使用服务器的所有 80 个核。 使用第一阶段的输出生成碰撞平均只需7.2秒。 一次碰撞平均需要测试 520 万次,最小和最大尝试次数分别超过 5000 次 1279 和 53M。 这证实了我们在4.3节中的分析。

    为了实现第 5.2 节中描述的多重攻击,我们必须顺序地运行约束和强制阶段,以生成两次碰撞。 我们的碰撞工具平均 15.2 秒就可以生成两个多重签名的bundle。 表2 显示了各阶段运行5000次所对应的平均时间以及最小和最大时间。

    6 讨论

    IOTA开发人员对漏洞的产生原因及其影响有过多次声明,我们对其进行了总结,并对部分问题作出了回应。

    IOTA开发人员认为我们的攻击模型与IOTA网络环境没有联系:具体来说就是,我们无法设置被签署过的消息,因为“在IOTA中,攻击者不会选择签名过的消息“[5]。为了应对这个问题,我们将攻击扩展到多重签名地址,因为多重签名协议明确允许一个用户选择另一个用户签名的消息。

    IOTA的开发人员还认为,”即使是大多数有效的攻击“都会在IOTA网络中失败,因为在闭源协调员中存在”保护机制” [5,13]。漏洞报告和本文中提出的攻击只单纯考虑如何应对IOTA签名方案,未在完整的IOTA系统的环境中分析这些攻击。

    此外,他们声称 Curl-P-27 可以接受碰撞输入是他们有意为之,其目的是防止克隆欺诈。其原话是:“IOTA 团队故意引入 Curl-P 哈希函数,以此预防[克隆欺诈],这还使得克隆欺诈无法用于 DLT 协议,同时保证了整个 IOTA 协议和网络的安全。”他们认为 “协调员会保护IOTA网络,不受故意引入的影响,并且称之为“复制保护机制”[13]。这么看来,我们除了发现一个新型攻击,似乎还发现了一个故意放置的后门。

    7 结论

    本文介绍了如何通过伪造消息签名来攻击IOTA签名方案。我们在两条消息只有一位字符不同的情况下构造了全状态碰撞。并且运用这个方法创建了两个有效的IOTA bundle,这样,就算两个bundle互不相同也仍然会映射到相同的值,也就是同一个签名将适用于两个bundle。 作为示例,我们在bundle中设置了不同的符码,攻击者可以在几十秒内使用简单的设备生成符合要求的bundle。

    8 致谢

    在此我们对 Andy Sellars, Weijia Gu, Rachael Walker, Joi Ito, Vincenzo Iozzo, Sharon Goldberg, and Ward Heilman 致以感谢,感谢你们对此论文的指导与建议。

    9 References

    [1] Mihir Bellare and Phillip Rogaway. “The exact security of digital signaturesHow to sign with RSA and Rabin”. In: International Conference on the Theory and Applications of Cryptographic Techniques. Springer. 1996, pp. 399– 416. 
    [2] Guido Bertoni et al. “On the indifferentiability of the sponge construction”. In: Lecture Notes in Computer Science 4965 (2008), pp. 181–197. 
    [3] Eli Biham and Adi Shamir. “Differential cryptanalysis of DES-like cryptosystems”. In: Journal of CRYPTOLOGY 4.1 (1991), pp. 3–72. 
    [4] Bitfinex. IOTA Protocol Upgrade August 08, 2017. https://www.bitfinex.com/posts/215, archived at https://web.archive.org/web/20180722235151/https://www.bitfinex.com/posts/215
    [5] Tangle blog. Full Emails of Ethan Heilman and the Digital Currency Initiative with the IOTA Team Leaked. http://www.tangleblog.com/wpcontent/uploads/2018/02/letters.pdf, archived at https://web. archive.org/web/20180228182122/http://www.tangleblog.com/wpcontent/uploads/2018/02/letters.pdf, https://archive.is/6imWR
    [6] Bosch. Press release: Robert Bosch Venture Capital makes first investment in distributed ledger technology. https://www.bosch- presse.de/pressportal/de/en/robert-bosch-venture-capital-makesfirst-investment-in-distributed-ledger-technology-137411.html, archived at https://web.archive.org/web/20180724022550/ https://www.bosch-presse.de/pressportal/de/en/robert-boschventure-capital-makes-first-investment-in-distributed-ledgertechnology-137411.html
    [7] Crypt Briefing. First VW IOTA Product Will Be Released Early Next Year. https://cryptobriefing.com/vw-iota-product-released/, archived at https://web.archive.org/web/20180724021409/https: //cryptobriefing.com/vw-iota-product-released/
    [8] Coindesk. City of Taipei Confirms It’s Testing IOTA Tech for ID. https://www.coindesk.com/city-of-taipei-confirms-its-testing-iotablockchain-for-id/
    [9] CoinmarketCap. CoinmarketCap IOTA July 23 2018. https://coinmarketcap. com/currencies/iota/, archived at https://web.archive.org/web/ 20180724020019/https://coinmarketcap.com/currencies/iota/
    [10] Michael Colavita and Garrett Tanzer. “A Cryptanalysis of IOTA’s Curl Hash Function”. In: (2018). 
    [11] Don Coppersmith. “The Data Encryption Standard (DES) and its strength against attacks”. In: IBM journal of research and development 38.3 (1994), pp. 243–250. 
    [12] IOTA Foundation. IOTA Guide – Generating Secure Multisig Addresses (hot and coldwallet). https://domschiener.gitbooks.io/iota-guide/content/exchange-guidelines/generating-multisignature-addresses.html, archived at https://archive.is/087kP
    [13] IOTA Foundation. Official IOTA Foundation Response to the Digital Currency Initiative at the MIT Media LabPart 4 / 4. https://blog.iota.org/official-iota-foundation-response-to-the-digitalcurrency-initiative-at-the-mit-media-lab-part-4-11fdccc9eb6d, archived at http://web.archive.org/web/20180727155405/https://blog.iota.org/official-iota-foundation-response-to-thedigital-currency-initiative-at-the-mit-media-lab-part-411fdccc9eb6d?gi=4be3ca82ed48
    [14] IOTAledger (github). IOTA Kerl specification. https://github.com/iotaledger/kerl/blob/master/IOTA-Kerl-spec.md, archived at https://web.archive.org/web/20180617175320/ 
    https://github.com/iotaledger/kerl/blob/master/IOTA-Kerl-spec.md. 2017. 
    [15] Oded Goldreich. Foundations of Cryptography: Basic Applications. Vol. 2. New York, NY, USA: Cambridge University Press, 2004. 
    [16] Guang Gong and Shaoquan Jiang. “The editing generator and its cryptanalysis”. In: International Journal of Wireless and Mobile Computing 1.1 (2005), pp. 46–52. 
    [17] Leon Groot Bruinderink and Andreas Hu¨lsing. ““Oops, I Did It Again” – Security of One-Time Signatures Under Two-Message Attacks”. In: Selected Areas in Cryptography – SAC 2017. 2018, pp. 299–322. 
    [18] Bertoni Guido et al. Cryptographic sponge functions. 2011. 
    [19] Paul Handy. Merged Kerl Implementation. https://github.com/iotaledger/iri/commit/539e413352a77b1db2042f46887e41d558f575e5, archived at https://archive.is/jCisX.
    [20] Ethan Heilman et al. IOTA Vulnerability Report: Cryptanalysis of the Curl Hash Function Enabling Practical Signature Forgery Attacks on the IOTA Cryptocurrency. 
    [21] Jonathan Katz and Yehuda Lindell. Introduction to Modern Cryptography. Second Edition. CRC Press, 2014. 
    [22] Leslie Lamport. Constructing digital signatures from a one-way function. Tech. rep. Technical Report CSL-98, SRI International Palo Alto, 1979. 
    [23] Willem Pinckaers (Lekkertech). IOTA Signatures, Private Keys and Address Reuse? http://blog.lekkertech.net/blog/2018/03/07/iotasignatures/, archived at https://archive.is/CnydQ. 2018. 
    [24] Arjen K. Lenstra, Xiaoyun Wang, and Benne de Weger. Colliding X.509 Certificates. Cryptology ePrint Archive, Report 2005/067. https://eprint. iacr.org/2005/067. 2005. 
    [25] Ralph C Merkle. “A certified digital signature”. In: Conference on the Theory and Application of Cryptology. Springer. 1989, pp. 218–238. 
    [26] Serguei Popov. “The tangle”. In: cit. on (2016), p. 131. 
    [27] Ralf Rottmann. IOTA Reclaim Identification Verification Process. https://blog.iota.org/iota-reclaim-identification-verificationprocess-e316647e06e6, archived at https://web.archive.org/web/ 20180710000243/https://blog.iota.org/iota-reclaim-identificationverification-process-e316647e06e6?gi=b8190e111e7f
    [28] Dominik Schiener. IOTA Multi-Signature Scheme. https://github.com/ iotaledger/wiki/blob/master/multisigs.mdIOTA Multi-Signature Scheme. 2017 (accessed February 3, 2018). 
    [29] Yonatan Sompolinsky and Aviv Zohar. “Secure high-rate transaction processing in bitcoin”. In: International Conference on Financial Cryptography and Data Security. Springer. 2015, pp. 507–527. 
    [30] Marc Stevens, Arjen Lenstra, and Benne de Weger. “Chosen-Prefix Collisions for MD5 and Colliding X. 509 Certificates for Different Identities”. In: Advances in Cryptology – EUROCRYPT 2007. Springer. 2007, pp. 1–22. 
    [31] Marc Stevens et al. “Short Chosen-Prefix Collisions for MD5 and the Creation of a Rogue CA Certificate”. In: Advances in Cryptology – CRYPTO 2009. Springer, 2009, pp. 55–69. 
    [32] David Snsteb. Upgrades & Updates. https://blog.iota.org/upgradesupdates-d12145e381eb, archived at https://web.archive.org/web/ 20180722232608/ 
    https://blog.iota.org/upgrades-updates-d12145e381eb?gi=51123f82db22
    [33] Eric Wall. IOTA is centralized. https://medium.com/@ercwl/iotais-centralized-6289246e7b4d, archived at https://web.archive.org/web/20180616231657/https://medium.com/@ercwl/iota-iscentralized-6289246e7b4d. 2017. 
    [34] Xiaoyun Wang and Hongbo Yu. “How to Break MD5 and Other Hash Functions”. In: Advances in Cryptology – EUROCRYPT 2005. Springer. 2005, pp. 19–35. 
    [35] Xiaoyun Wang et al. Collisions for Hash Functions MD4, MD5, HAVAL128 and RIPEMD. Cryptology ePrint Archive, Report 2004/199. https://eprint.iacr.org/2004/199.2004.


    Paper

    本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/1015/

    作者:吴烦恼 | Categories:安全研究 | Tags:
  • 对某单位的 APT 攻击样本分析

    2019-08-21

    作者:SungLin@知道创宇404实验室
    时间:2019年7月30日

    一.恶意邮件样本的信息与背景

    在六月份的某单位HW行动中,知道创宇HW安全团队通过创宇云图APT威胁感知系统并结合腾讯御点终端安全管理系统成功处置了一起APT攻击事件。

    7月份对同一样本的补充截图如下:

    在本次APT攻击中,攻击者通过发送鱼叉式钓鱼邮件,配合社会工程学手段诱导用户运行宏代码,进而下载尾部带有恶意payload压缩包的可执行文件。通过层层释放最终运行可窃取受害人员各类机密信息、维持权限、接收远端控制的木马。

    文档打开后,会诱导用户需要开启宏才能查看被模糊的图片,一旦用户点击开启宏,恶意样本将会在用户电脑上运行、潜伏、收集相应的信息、等待攻击者的进一步指令。

    该APT样本整体运行流程图如下:

    二.宏病毒文档的提取与调试

    使用OfficeMalScanner解压Office文档并提取文档所带的vba宏代码,打开Office文档启用宏后,采用快捷键Alt+F11开启宏代码的动态调试。该宏代码作为实施攻击的入口,实现了恶意样本的下载和执行。本章也将分析下载和执行的整体流程。

    解压该Office文档后,宏代码被封装在xl文件夹下的vbaProject.bin文件中。

    使用OfficeMalScanner这个工具的命令info从vbaProject.bin中提取宏代码,提取完后可以知道有6个宏代码,其中fdrhfaz2osd是主要的宏代码:

    动态调试分析宏代码,首先宏代码传入两个值u和f,分别是请求的url和写入的filepath。

    通过调用WinHttp.WinHttpRequest模块的方法Get请求来获取Response并写入到文件gc43d4unx.exe中。

    最后通过调用WScript.Shell来启动程序gc43d4unx.exe。

    三.gc43d4unx.exe释放pkk.exe等文件并执行

    程序gc43d4unx.exe在文件的末尾存放了一个RAR的压缩文件,gc43d4unx.exe程序通过解压缩后在用户Temp目录下的29317159文件夹释放了49个文件,并以pkk.exe xfj=eaa命令继续执行恶意样本。

    压缩文件在gc43d4unx.exe中的分布情况。

    gc43d4unx.exe主要逻辑在对话框的回调函数sub_419B4E中,识别Rar!的头部标识

    解压缩到映射的内存文件中,然后再挨着写到各个文件中

    在用户Temp目录下的29317159文件夹生成隐藏文件

    最后通过SHELL32.ShellExecuteExW执行qwb.vbs代码,qwb.vbs则会使用WshShell.Run运行pkk.exe xfj=eaa。

    四.PayLoad之pkk.exe运行分析

    pkk.exe是个名为AutoIt v3的脚本软件,可以加载自定义脚本。主要是就是通过定义DllStruct,然后再通过DllCall来调用函数。qwb.vbs运行代码为WshShell.Run”pkk.exe xfj=eaa”,通过pkk.exe加载一个叫xfj=eaa的二进制文件。

    软件先判断载入的是不是DLL,xfj=eaa是个编码后的脚本,判断后程序将会尝试解码。

    解码成功后,将解码数据写入一个临时文件中,软件将会重新创建一个进程来重新加载脚本。

    解码后的Autolt脚本,代码被混淆了。

    根据混淆的脚本,只是函数名混淆,而且脚本只是一个纯文本代码,通过重写此脚本后,可以看到基本还原的Autolt脚本代码了。

    Autolt软件解析完脚本后根据字符串功能通过分发函数来执行相应的函数。

    五.PayLoad之Autolt脚本分析

    Autolt脚本包含的功能有:检测运行环境、修改注册表、解密最终的.net木马并运行。

    通过检测进程名、设备是否有D盘等操作实现反虚拟机检测

    注册表禁用UAC策略函数

    注册表禁用任务管理器函数

    注册表开启自启函数,AuEx和ExE_c的值分别是xfj=eaa、pkk.exe。

    解密.net木马:

    读取K3ys这个键值和mmm.ini文件中[Data]段到[eData],将此数据进行字符替换正则匹配。

    载入Advapi32.dll,将K3ys键值进行Hash计算获取到真正的key,后再调用CryptDecrypt函数解密,利用ollydbg动态调试dump出解密数据,解密后的数据就是一个PE结构的程序,用IDA分析程序后,为.NET程序,这个.NET程序就是最后核心木马了,Autolt脚本后续将此PE结构加载进去,创建线程去单独运行此程序。

    六..NET木马分析

    木马主要功能进行了敏感信息收集,敏感信息收集完后会判断目标主机是否符合收集目标,以判断6个人名为主,符合本机收集目标,将会通过smtp或者ftp服务器上传文件,并且也通过web服务和c&c进行信息交流等。

    木马程序的基本信息:

    用.net反编译工具dnSpy打开此程序,程序入口处就是在类afg.agu,此木马经我判定进行了控制流扁平化和字符串加密的混淆方式,采用工具de4dot无法进行反混淆。

    字符串的解密:

    如下图所示,经过字符串加密后静态分析已经无法分析到字符串,而且可以看出控制流进行了扁平化的处理,加密字符串的入口函数为<Module>.\u206E()

    字符串的加密方式主要是通过传入加密的索引,通过固定值的替换与拆分计算后找到对应存储在uint型数组对象\u2009的加密Data、key、IV,\u2009数组对象大概有1047个字符串加密数组,字符串加密采用AES,模式为CBC。

    编写python脚本进行了字符串解密,解密后的效果如下所示:

    字符串解密核心算法如下:

    入口处获取主机名进行判断是否包含以下6个主机名,攻击目标是否符合:

    自我复制到C:\Users\l\AppData\Roaming\MyApp\MyApp.exe,设置为系统文件,并设置为无法删除的文件Zone.Identifier,在注册表设置为自启应用并且隐藏。

    感谢前辈的指点,此处有错误,更正如下:定时请求 http://checkip.amazonaws.com/ 获取出口的IP。

    httpweb服务器进行交互,进行信息的交流包括("update"、"info"、"uninstall"、"cookies"、"screenshots"、"keylog")。

    DNS查询等:

    进行ftp和smtp服务操作,并且绑定了一个邮箱地址 。

    以下可能是此地址的密码:

    收集信息如下:

    系统信息
    ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_VideoController")
    managementObjectSearcher2 = new ManagementObjectSearcher("SELECT * FROM Win32_Processor");
    浏览器
    CatalinaGroup\Citrio\User Dataliebao\User Data
    Fenrir Inc\Sleipnir5\setting\modules\ChromiumViewerYandex\YandexBrowser\User Data
    360Chrome\Chrome\User DataChedot\User Data
    Elements Browser\User DataEpic Privacy Browser\User Data
    CocCoc\Browser\User DataMapleStudio\ChromePlus\User Data
    Chromium\User DataTorch\User Data
    Iridium\User DataComodo\Dragon\User Data
    7Star\7Star\User DataAmigo\User Data
    BraveSoftware\Brave-Browser\User DataCentBrowser\User Data
    Vivaldi\User DataQIP Surf\User Data
    Kometa\User DataOrbitum\User Data
    Sputnik\Sputnik\User DatauCozMedia\Uran\User Data
    Coowon\Coowon\User Data
    ftp列表
    \CoreFTP\sites.idx\FTP Navigator\Ftplist.txt
    \SmartFTP\Client 2.0\Favorites\Quick Connect\
    \SmartFTP\Client 2.0\Favorites\Quick Connect*.xml\Ipswitch\WS_FTP\Sites\ws_ftp.ini
    \cftp\Ftplist.txt\FTPGetter\servers.xml
    \FTP Navigator\Ftplist.txt
    Mail列表
    \VirtualStore\Program Files\Foxmail\mail\\Opera Mail\Opera Mail\wand.dat
    Software\IncrediMail\Identities\
    注册表
    "HKEY_CURRENT_USER\Software\FTPWare\COREFTP\Sites\" + str + "Host""HKEY_CURRENT_USERSoftwareFTPWareCOREFTPSites" + str + "Port"
    "HKEY_CURRENT_USERSoftwareFTPWareCOREFTPSites" + str + "User""HKEY_CURRENT_USERSoftwareFTPWareCOREFTPSites" + str + "PW"
    "HKEY_CURRENT_USERSoftwareFTPWareCOREFTPSites" + str + "Name"

    http通信信息

    七.安全建议

    强烈推荐采用知道创宇云图、腾讯御点等产品,提高企业安全保护,降低外部威胁水平。

    知道创宇云图威胁监测系统系列产品,实时分析网络全流量,结合威胁情报数据及网络行为分析技术,深度检测所有可疑活动。文件检测采用全面沙箱分析,通过在沙箱(Sandbox)中运行(行为激活/内容“引爆”)各种文件,分析文件行为,识别出未知威胁。网络检测与文件检测同步进行,采用情报共享机制,构筑检测生态圈,准确、快速地掌握攻击链条,以便进一步采取相关措施,将APT(高级持续性威胁)攻击阻止在萌芽状态。

    腾讯御点是腾讯出品、领先国际的企业级安全服务提供者。依托腾讯19年的安全经验积累,为企业级用户提供私有云防病毒和漏洞修复解决方案。御点具备终端杀毒统一管控、修复漏洞统一管控,以及策略管控等全方位的安全管理功能,可帮助企业管理者全面了解、管理企业内网安全状况、保护企业安全。

    八.IOC信息

    domain & IP:

    相关 hash:

    7b478598b056d1f8e9f52f5ef1d147437b7f0da5
    a73816ebcfc07d6da66de7c298a0912a3dd5d41a
    b65884f1e833ea3eec8a8be4c7057a560da4511e
    8827b2c1520fb41034d5171c5c4afd15158fd4a3
    491b221f68013a2f7c354e4bb35c91fe45a1c0c0


    Paper

    本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/1011/

    作者:吴烦恼 | Categories:安全研究 | Tags:
  • Apache Solr DataImportHandler远程代码执行漏洞(CVE-2019-0193) 分析

    2019-08-21

    作者:Longofo@知道创宇404实验室 
    时间:2019年8月8日

    漏洞概述

    2019年08月01日,Apache Solr官方发布预警,Apache Solr DataImport功能 在开启Debug模式时,可以接收来自请求的"dataConfig"参数,这个参数的功能与data-config.xml一样,不过是在开启Debug模式时方便通过此参数进行调试,并且Debug模式的开启是通过参数传入的。在dataConfig参数中可以包含script恶意脚本导致远程代码执行。

    我对此漏洞进行了应急,由于在应急时构造的PoC很鸡肋,需要存在数据库驱动,需要连接数据库并且无回显,这种方式在实际利用中很难利用。后来逐渐有新的PoC被构造出来,经过了几个版本的PoC升级,到最后能直接通过直接传递数据流的方式,无需数据库驱动,无需连接数据库且能回显。下面记录下PoC升级的历程以及自己遇到的一些问题。感谢@Badcode与@fnmsd师傅提供的帮助。

    测试环境

    分析中涉及到的与Solr相关的环境如下:

    • Solr-7.7.2
    • JDK 1.8.0_181

    相关概念

    一开始没有去仔细去查阅Solr相关资料,只是粗略翻了下文档把漏洞复现了,那时候我也觉得数据应该能回显,于是就开始调试尝试构造回显,但是没有收获。后来看到新的PoC,感觉自己还没真正明白这个漏洞的原理就去盲目调试,于是又回过头去查阅Solr资料与文档,下面整理了与该漏洞有关的一些概念。

    Solr工作机制

    1.solr是在lucene工具包的基础之上进行了封装,并且以web服务的形式对外提供索引功能

    2.业务系统需要使用到索引的功能(建索引,查索引)时,只要发出http请求,并将返回数据进行解析即可

    (1) 索引数据的创建

    根据配置文件提取一些可以用来搜索的数据(封装成各种Field),把各field再封装成document,然后对document进行分析(对各字段分词),得到一些索引目录写入索引库,document本身也会被写入一个文档信息库

    (2) 索引数据的查询

    根据关键词解析(queryParser)出查询条件query(Termquery),利用搜索工具(indexSearcher)去索引库获取文档id,然后再根据文档id去文档信息库获取文档信息

    Solr DataImportHandler

    Solr DataImportHandler可以批量把数据导入到索引库中,根据Solr文档中的描述,DataImportHandler有如下功能:

    • 读取关系数据库中数据或文本数据
    • 根据配置从xml(http/file方式)读取与建立索引数据
    • 根据配置聚合来自多个列和表的数据来构建Solr文档
    • 使用文档更新Solr(更新索引、文档数据库等)
    • 根据配置进行完全导入的功能(full-import,完全导入每次运行时会创建整个索引)
    • 检测插入/更新字段并执行增量导入(delta-import,对增加或者被修改的字段进行导入)
    • 调度full-import与delta-import
    • 可以插入任何类型的数据源(ftp,scp等)和其他用户可选格式(JSON,csv等)

    通过搜索到的资料与官方文档中对DataImportHandler的描述,根据我的理解整理出DataImport处理的大致的流程图如下(只画了与该漏洞相关的主要部分):

    几个名词解释:

    • Core:索引库,其中包含schema.xml/managed-schema,schema.xml是模式文件的传统名称,可以由使用该模式的用户手动编辑,managed-schema是Solr默认使用的模式文件的名称,它支持在运行时动态更改,data-config文件可配置为xml形式或通过请求参数传递(在dataimport开启debug模式时可通过dataConfig参数传递)

    通过命令行创建core

    -d 参数是指定配置模板,在solr 7.7.2下,有_default与sample_techproducts_configs两种模板可以使用

    通过web页面创建core

    一开始以为从web页面无法创建core,虽然有一个Add Core,但是点击创建的core目录为空无法使用,提示无法找到配置文件,必须在solr目录下创建好对应的core,在web界面才能添加。然后尝试了使用绝对路径配置,绝对路径也能在web界面看到,但是solr默认不允许使用除了创建的core目录之外的配置文件,如果这个开关设为了true,就能使用对应core外部的配置文件:

    后来在回头去查阅时在Solr Guide 7.5文档中发现通过configSet参数也能创建core,configSet可以指定为_default与sample_techproducts_configs,如下表示创建成功,不过通过这种方式创建的core的没有conf目录,它的配置是相当于链接到configSet模板的,而不是使用copy模板的方式:

    通过以上两种方式都能创建core,但是要使用dataimport功能,还是需要编辑配置solrconfig.xml文件,如果能通过web请求方式更改配置文件以配置dataimport功能就能更好利用这个漏洞了。

    schema.xml/managed-schema:这里面定义了与数据源相关联的字段(Field)以及Solr建立索引时该如何处理Field,它的内容可以自己打开新建的core下的schema.xml/managed-schema看下,内容太长就不贴了,解释下与该漏洞相关的几个元素:

    dataConfig:这个配置项可以通过文件配置或通过请求方式传递(在dataimport开启Debug模式时可以通过dataConfig参数),他配置的时怎样获取数据(查询语句、url等等)要读什么样的数据(关系数据库中的列、或者xml的域)、做什么样的处理(修改/添加/删除)等,Solr为这些数据数据创建索引并将数据保存为Document

    PoC进化历程

    PoC第一阶段--数据库驱动+外连+无回显

    根据官方漏洞预警描述,是DataImportHandler在开启Debug模式时,能接收dataConfig这个参数,这个参数的功能与data-config.xml一样,不过是在开启Debug模式时方便通过此参数进行调试,并且Debug模式的开启是通过参数传入的。在dataConfig参数中可以包含script脚本,在文档搜到一个ScriptTransformer的例子:

    可以看到在script中能执行java代码,于是构造下PoC(通过logs查看相关报错信息查看PoC构造出现的问题),这个数据库是可以外连的,所以数据库的相关信息可以自己控制,测试过是可以的(只是演示使用的127.0.0.1):

    在ScriptTransformer那个例子中,能看到row.put的字样,猜测应该是能回显的,测试下:

    这里只能查看id字段,name字段看不到,也没有报错,然后尝试了下把数据put到id里面:

    能看到回显的信息。一开始不知道为什么put到name不行,后来看到在第三阶段的PoC,又回过头去查资料才意识到dataConfig与schema是配合使用的。因为在schema中没有配置name这个field,但是默认配置了id这个fileld,所以solr不会把name这个字段数据放到Document中去而id字段在其中。在第三阶段的PoC中,每个Field中的name属性都有"_s",然后去搜索发现可以在schema配置文件中可以配置dynamicField,如下是默认配置好的dynamicField:

    在上面的相关概念中对这个字段有介绍,可以翻上去查看下,测试下,果然是可以的:

    只要dynamicField能匹配dataConfig中field的name属性,solr就会自动加到document中去,如果schema配置了相应的field,那么配置的field优先,没有配置则根据dynamicField匹配。

    PoC第二阶段--外连+无回显

    在文档中说到JdbcDataSource可以使用JNDI,

    测试下能不能进行JNDI注入:

    这里有一个JNDI+LDAP的恶意demo。使用这种方式无需目标的CLASSPATH存在数据库驱动。

    PoC第三阶段--无外连+有回显

    这个阶段的PoC来自@fnmsd师傅,使用的是ContentStreamDataSource,但是文档中没有对它进行描述如何使用。在stackoverflower找到一个使用例子:

    在相关概念中说到了ContentStreamDataSource能接收Post数据作为数据源,结合第一阶段说到的dynamicField就能实现回显了。

    只演示下效果图,不给出具体的PoC:

    后来回过头去看其他类型的DataSource时,使用URLDataSource/HttpDataSource也可以,文档中提供了一个例子:

    构造测试也是可行的,可以使用http、ftp等协议

    参考链接


    Paper

    本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/1009/

    作者:吴烦恼 | Categories:安全研究 | Tags:
  • KDE4/5 命令执行漏洞 (CVE-2019-14744) 简析

    2019-08-21

    作者: HACHp1@知道创宇404实验室 
    日期: 2019/08/08

    漏洞简介

    KDE Frameworks是一套由KDE社群所编写的库及软件框架,是KDE Plasma 5及KDE Applications 5的基础,并使用GNU通用公共许可证进行发布。其中所包含的多个独立框架提供了各种常用的功能,包括了硬件集成、文件格式支持、控件、绘图功能、拼写检查等。KDE框架目前被几个Linux发行版所采用,包括了Kubuntu、OpenMandriva、openSUSE和OpenMandriva。

    2019年7月28日Dominik Penner(@zer0pwn)发现了KDE framework版本<=5.60.0时存在命令执行漏洞。

    2019年8月5日Dominik Penner在Twitter上披露了该漏洞,而此时该漏洞还是0day漏洞。此漏洞由KDesktopFile类处理.desktop或.directory文件的方式引起。如果受害者下载了恶意构造的.desktop或.directory文件,恶意文件中注入的bash代码就会被执行。

    2019年8月8日,KDE社区终于在发布的更新中修复了该漏洞;在此之前的三天内,此漏洞是没有官方补丁的。

    一些八卦

    • 在Dominik Penner公开此漏洞时,并没有告诉KDE社区此漏洞,直接将该0day的攻击详情披露在了Twitter上。公布之后,KDE社区的人员与Penner之间发生了很多有意思的事情,在这里不做描述。

    影响版本

    • 内置或后期安装有KDE Frameworks版本<=5.60.0的操作系统,如Kubuntu。

    漏洞复现

    环境搭建

    • 虚拟机镜像:kubuntu-16.04.6-desktop-amd64.iso
    • KDE Framework 5.18.0
    • 搭建时,注意虚拟机关闭网络,否则语言包下载十分消耗时间;此外,安装完成后进入系统要关掉iso影响,否则无法进入系统。

    复现过程及结果

    PoC有多种形式,此处使用三种方式进行复现,第1、2种为验证性复现,第3种为接近真实情况下攻击者可能使用的攻击方式。

    1.PoC1: 
    创建一个文件名为”payload.desktop”的文件:

    在文件中写入payload:

    保存后打开文件管理器,写入的payload被执行:

    文件内容如下:

    2.PoC2:

    创建一个文件名为” .directory”的文件:

    使用vi写入内容(此处有坑,KDE的vi输入backspace键会出现奇怪的反应,很不好用):

    写入payload:

    保存后打开文件管理器,payload被成功执行:

    3.PoC3: 
    攻击者在本机启动NC监听:

    攻击者将payload文件打包挂载至Web服务器中,诱导受害者下载:

    受害者解压文件:

    解压后,payload会被执行,攻击者接收到反连的Shell:

    • 漏洞影响:虽然直接下载文件很容易引起受害者注意,但攻击者可以将恶意文件打包为压缩文件并使用社会工程学诱导受害者解开压缩包。不管受害者有没有打开解压后的文件,恶意代码都已经执行了,因为文件解压后KDE系统会调用桌面解析函数。此时受害者就容易中招。

    漏洞原理简析

    • 在Dominik Penner公布的细节中,对该漏洞已经有着比较详细的解释。在着手分析漏洞前,我们先学习一下Linux的desktop entry相关的知识。

    desktop entry

    • XDG 桌面配置项规范为应用程序和桌面环境的菜单整合提供了一个标准方法。只要桌面环境遵守菜单规范,应用程序图标就可以显示在系统菜单中。
    • 每个桌面项必须包含 Type 和 Name,还可以选择定义自己在程序菜单中的显示方式。
    • 也就是说,这是一种解析桌面项的图标、名称、类型等信息的规范。
    • 使用这种规范的开发项目应该通过目录下的.directory.desktop文件记录该目录下的解析配置。

    详见:https://wiki.archlinux.org/index.php/Desktop_entries_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)

    漏洞的产生

    KDE的桌面配置解析参考了XDG的方式,但是包含了KDE自己实现的功能;并且其实现与XDG官方定义的功能也有出入,正是此出入导致了漏洞。

    在KDE文档中有如下的话(https://userbase.kde.org/KDE_System_Administration/Configuration_Files#Shell_Expansion):

    • 为了提供更加灵活的设置解析,KDE实现并支持了动态配置,而此处的${USER}尤其令人注意,该项取自环境变量,可以推测,此处与命令执行肯定有联系。
    • 每当KDE桌面系统要读取图标等桌面配置时,就会调用一次readEntry函数;从Dominik Penner给出的漏洞细节中,可以看到追踪代码的过程。整个漏洞的执行过程如下: 
      首先,创建恶意文件:

    进入文件管理器,此时系统会对.desktop文件进行解析;进入解析Icon的流程,根据文档中的说明,参数中带有[$e]时会调用shell动态解析命令:

    kdesktopfile.cpp:

    跟进,发现调用了KConfigPrivate::expandString(aValue): 
    kconfiggroup.cpp:

    再跟进,结合之前对KDE官方文档的解读,此处是对动态命令的解析过程,程序会把字符串中第一个出现的$(与第一个出现的)之间的部分截取出来,作为命令,然后调用popen执行: 
    kconfig.cpp

    自此,漏洞利用过程中的代码执行流程分析完毕;可以看到KDE在解析桌面设置时,以直接使用执行系统命令获取返回值的方式动态获得操作系统的一些参数值;为了获得诸如${USER}这样的系统变量直接调用系统命令,这个做法是不太妥当的。

    官方修补方案分析

    • 官方在最新版本中给出了简单粗暴的修复手段,直接删除了popen函数和其执行过程,从而除去了调用popen动态解析[e]属性的功能:
    • 此外,官方还不忘吐槽了一波:

    总结

    • 个人认为这个漏洞在成因以外的地方有着更大的意义。首先,不太清楚当初编写KDE框架的开发人员的用意,也许是想让框架更灵活;但是在文档的使用用例中,只是为了获取${USER}变量的值而已。在命令执行上有些许杀鸡用牛刀的感觉。
    • 从这个漏洞可以看出灵活性与安全性在有的时候是互相冲突的,灵活性高,也意味着更有可能出现纰漏,这给开发人员更多的警示。
    • 漏洞发现者在没有通知官方的情况下直接公布了漏洞细节,这个做法比较有争议。在发现漏洞时,首先将0day交给谁也是个问题,个人认为可以将漏洞提交给厂商,待其修复后再商议是否要公布。可能国际上的hacker思维与国内有着比较大的差异,在Dominik Penner的Twitter下竟然有不少的人支持他提前公布0day,他自己也解释是想要在defcon开始之前提交自己的0day,这个做法以及众人的反应值得去品味。

    参考资料


    Paper

    本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/1006/

    作者:吴烦恼 | Categories:安全研究 | Tags:
  • 总结:IOTA反驳DCI实验室提出的漏洞荒谬至极

    2019-08-21

    原文:https://medium.com/@noahruderman/a-summary-of-why-iotas-refutation-of-a-vulnerability-by-dci-labs-is-absurd-128e894781b1 
    作者:Noah Ruderman 
    译者:知道创宇404实验室

    DCI实验室发布报告称,他们发现了针对IOTA交易签名方案中存在性不可伪造(EU-CMA)的安全问题,允许攻击者窃取资金。

    而对于密码学来说,这个漏洞正是密码学安全研究的向量。如果你不同意这一点,你就是在反对密码学。

    1. 前言

    争议开始于由麻省理工学院旗下的DCI实验室撰写的漏洞报告。IOTA开发人员否认密码学和互联网安全对漏洞的定义,指控DCI实验室学术欺诈,并骚扰DCI的安全研究员伊森·海尔曼,威胁说要对这份不利的漏洞报告采取法律行动。

    尽管DCI声称的漏洞在每一位加密专家、安全研究人员和主要加密货币开发人员看来都是正确的,但这很难令常人所理解。在这基础上,IOTA强烈反对curl-p易受攻击的观点,并发布了相关文章

    本篇文章的目的: 
    (a) 向几乎没有密码学知识的人解释该漏洞的性质; 
    (b) 为什么IOTA的反驳并不能说服密码学专家和安全研究人员; 
    (c) 如何论证哈希函数的安全性。

    2. DCI实验室声明的摘要

    DCI实验室表示,用于保护交易安全的数字签名方案不符合EU-CMA的安全概念。该数字签名方案的安全性之所以能被打破,是因为所使用的哈希函数curl-p没有抗碰撞的属性。

    3. 什么是curl-p?

    Curl-p是一个哈希函数。哈希函数将任意长度的数据转换为固定长度的输出。你可以将这些输出看作数字指纹。哈希函数旨在满足以下主要特性:

    • 确定性:给定相同的输入,获取的哈希值始终相同。
    • 一致性:预期的输入应尽可能一致地映射到输出范围。
    • 不可逆性:给定哈希值,应该很难找到相应的输入。但“非常困难”的定义很宽泛,因为它取决于许多外部因素,比如随着时间推移而变化的技术,但专家们对此没有争议。在普通硬件上计算冲突是不可能的,并且对于安全的哈希函数来说,任何人都很难找到冲突。如果政府能够找到冲突,那么哈希函数就不会被认为是安全的。

    curl-p的目的是使哈希函数表现出高度随机的行为,它使我们将哈希值视为唯一的且防篡改的。

    4. curl-p的作用是什么?

    Curl-p是由Sergey Ivancheglo编写的自定义哈希函数,他也被称为Come-from-Beyond。它是数字签名方案的一部分,用于确保交易的身份验证的完整性。在消息上构造数字签名的过程包括将数据哈希并用私钥加密哈希值。这是加密货币的标准做法。详细解释如下:

    • 身份验证:证明消息是由公钥所有者创建的。如果消息未经过哈希处理,则签名会更长,则需要更多时间进行验证。
    • 完整性:防止消息在创建后被篡改,同时仍然在数字签名下进行验证。

    数字签名是通过用公钥解密签名并将交易数据哈希来进行验证的。如果未加密签名和相应的哈希值相同,则认为数字签名有效。

    然而,预期中的数字签名要求哈希函数表现出高度的随机行为。如果curl-p表现出足够的非随机行为,攻击者就可以构造一个没有私钥签名但具有相同签名的消息,因为消息的哈希值是相同的。这意味着数字签名方案被破坏,攻击者可能会伪造交易来窃取资金,因此交易的数字签名(扩展为curl-p)在软件生产中具有关键的安全作用。

    5. curl-p必须满足哪些安全属性才能防止攻击?

    我们可以简单的把这个问题归结为冲突,即两则不同的消息可以用curl-p哈希得到相同值的频率。如果两则消息哈希值相同,那么签名将是相同的,如果攻击者的消息是有效的交易,这意味着可能有人通过使用前一个交易的签名来使用你的Iota币。任何curl-p的冲突都会对数字签名方案发起攻击,因此curl-p应该具有最强的安全性。

    用于满足最严格的安全属性的哈希函数被称为加密哈希函数。这些安全属性包括:

    • 抗碰撞性:攻击者应该无法找到两则消息m1和m2使得hash(m1) = hash(m2)。
    • 抗原像攻击:如果提供哈希值h,攻击者应该无法找到消息m使得m = hash(h)。
    • 抗第二原像攻击:如果提供消息m1,攻击者应该无法找到消息m2,使得hash(m1)= hash(m2),m1!= m2。

    6. curl-p是加密哈希函数吗?

    IOTA开发人员一直含糊其辞,但更频繁地声称curl-p并非旨在成为加密哈希函数。他们反驳了DCI实验室关于漏洞的说法,因为他们认为在curl-p中不需要抗碰撞性。换句话说,他们不能因为curl-p是一个不安全的哈希函数而被指责,因为它从来没有打算保证curl-p是安全的。

    然而,curl-p在确保使用拥有超过10亿美元生产系统的安全方面发挥了关键作用。curl-p的充分非随机行为可能使资金被盗。除非允许资金窃取是curl-p的预期功能,否则其应该被设计为满足我概述的最严格的安全属性,这将使其成为加密哈希函数。如果按照IOTA开发人员所说,curl-p并不是一个加密哈希函数,那么这就是一个重大的设计缺陷。

    因此,IOTA开发人员要么为其极其糟糕的设计负责,要么认为他们自己构建了一个安全的哈希函数,因为他们无法找到破解它的方法。两者都表现出极差的判断力,第一种是健忘,第二种是对其安全性过于自信。

    7. 是否存在漏洞?

    存在。DCI实验室发现curl-p并不具有抗碰撞性,他们展示了两则消息的真实例子,这两则消息被网络视为有效交易,但是哈希到相同的值。他们通过利用curl-p中的非随机行为来改变消息中的一些位以生成哈希值相同的新值。这些位就是交易金额。因此,如果你向某人发送了一些Iota币,那么你可以通过修改交易来发送不同的金额。

    DCI实验室还展示了理论上的攻击是如何通过破坏抗碰撞性来实现的。你可以构造两项哈希值相同的交易来发送Alice的Iota币,然后让Alice签署第一项交易,然后用这个签名发送第二项交易。

    正如密码学专家、安全研究人员等普遍理解的那样,漏洞确实存在,原因如下:商用硬件上的curl-p上发生了碰撞;curl-p中被打破的抗碰撞性是用来自同一地址的事务来表示的;使用curl-p来哈希交易数据意味着用户资金可能被盗;加密哈希函数不可能实现这一点……

    但如果我认为这次攻击没有那么严重呢?

    “安全”(secure)一词用于哈希函数,“漏洞”(vulnerability)一词用于软件,它们都有明确的定义,这些定义独立于任何人对这些攻击破坏力的感受。密码学对数字签名方案的安全性有严格的定义,且数字签名方案的安全性也与个人感受无关。因此,我们完全可以说curl-p是不安全的,并且其存在一个漏洞,但攻击并没有那么严重。因为攻击没有那么严重,所以不存在漏洞这种说法是不正确的。

    8. 为什么要考虑标准的EU-CMA而不是实际的攻击呢?

    没有受过软件工程或密码学培训的人最常犯的一个错误是,EU-CMA攻击是一个抽象的游戏,不能很好地转化为实际的结果。毕竟,IOTA的协调员可能自己做了一些验证,这肯定会影响概述的攻击的可行性,而这并不是EU-CMA模拟的一部分。当然也有一些外部组件对攻击很重要——不建议重用地址。让我们先把明显的细节放在一边,即协调器是一个临时措施,而且它是闭源的——这意味着没有人知道它到底做了什么。

    如果关于系统安全性的评判标准是“能否在生产系统中演示实际的攻击”,那么在实际部署这些演示时,会出现一些明显的问题。首先,黑客攻击计算机系统是违法的。其次是关于安全漏洞的微妙本质——你真的认为等到商用硬件上的SHA-1被破坏后再将其用于关键的互联网基础设施是一个好主意吗?还有一个事实是,闭源代码是不能进行公开访问的——你认为我们应该忽略那些闭源系统的安全性吗?这样的例子不胜枚举。

    如何解释安全性的标准,你可以将其视为最佳实践。最佳实践就像专家的常识一样,因为同样的错误往往会重复出现——比如创建自定义的哈希函数。EU-CMA攻击包含了我们期望从构建了安全方面的最佳实践的系统中看到的行为。也就是说,如果你实现了EU-CMA关于数字签名安全的概念,那么你就知道存在某些安全保证,甚至不需要为系统的各个部分创建巨大的流程图。从另一个角度来看,如果你系统的安全性依靠外部验证来维护被破坏的协议的完整性,那么你就会有一个过于草率、复杂的系统,它很容易出现安全漏洞。

    Sergey说EU-CMA对数字签名不重要,因为他的系统会做额外的验证,这就像在说:

    • 你不用担心把所有的硬币都放在一个热钱包里,因为没有人知道这台电脑在哪里以及它的密码。
    • 你不必用VPN来向政府隐藏你的IP,因为他们的隐私政策说他们不保存日志。
    • 你无需为重复使用密码而担心,因为密码的安全性很高。

    这些例子听起来很愚蠢吗?当然!但它们本质一样。安全漏洞在技术上可以通过外部因素得到缓解。但是这种缓和因素是非常脆弱的,特别是对那些安全因素至关重要的东西来说。如果与大型热钱包交易可以获得10亿美元呢?它完全打破了你的安全模式。IOTA开发人员冒着损失用户10亿美元的风险——用他们自己的话说,因为他们不知道有比在生产系统中测试未经同行评审的自定义加密原语更好的方法,也不知道有比只是部署它并查看是否有人破坏了它更好的方法——这极其荒谬。(参见:泄露邮件第4封)

    9. 如果现实生活中的攻击看起来还不那么切合实际,为什么安全研究人员还会担心呢?

    因为哈希函数的历史给了我们一些教训,那就是第一个漏洞只是开始,随着时间的推移,会发现更多的漏洞。DCI团队非常接近于找到一个原像攻击,他们先发制人地声明他们与IOTA进行了私下交流。DCI实验室表示,他们认为这是有可能的,但还无法对其进行量化。他们还认为curl-p也破坏了抗原像攻击,而并不难以置信。

    如果发现了curl-p的原像攻击,那么实际的攻击将十分危急且无法恢复。原像攻击意味着你不需要为消息签名攻击就可以成功。想象一下攻击者设置了大量的Iota完整节点。现在使用一个轻钱包连接这些节点,并传播你的交易。该交易不会被传到网上。相反地,他们会伪造一个假交易,然后用你的签名进行传播。

    10. 将SHA-1作为哈希函数安全性的案例研究

    显示非随机行为迹象的哈希函数只是一个开始。SHA-1于1995年被正式指定。2005年,在其规范化整整十年后,漏洞开始被发布,其攻击力比暴力攻击更有效。与curl-p不同的是,在2005年的时候还没有发现实际的碰撞。SHA-1提供的安全性比承诺的要低,差距太小而不容忽视,可能在政府的预算范围内无法攻破,但这足以让密码学界认为它是不安全的。

    在接下来的几年里,打破SHA-1安全性的障碍不断变小,并且完全在政府的掌控之中。同样地,尽管没有发现碰撞事实,但许多组织都建议用SHA-2或SHA-3来代替SHA-1。2017年,终于发现了一次碰撞。这是一次碰撞攻击,他们证明它可以用来做一些事情,比如构造一个低租金的合同,用具有相同哈希值的高租金合同来交换数字签名。

    SHA-1的历史总结:

    • 第一个漏洞是在其规范之后整整十年才发现的。
    • 一旦攻击被证明比暴力更有效时,密码学家就认为它是不安全的,尽管这是不切实际的。没有一个密码学家认为SHA-1是安全的,因为它太难攻击了。
    • 尽管在2017年之前,没有人负担得起在SHA-1中发现碰撞的计算能力,但政府完全有能力做到这一点。
    • 自2005年以来,每年对SHA-1的攻击都变得越来越高效。换句话说,一旦SHA-1显示出非随机行为,对它的尝试性利用变得越来越好。

    与此curl-p比较:

    • 第一个漏洞是在IOTA在交易所上市后一个月内发现的,该项目也因此受到公众关注,市值超过10亿美元。而SHA-1花了10年的时间才得到研究人员的关注。
    • 尽管curl-p在保护签名完整性方面与SHA-1有类似的作用,但Sergey Ivancheglo并不认为抗碰撞性很重要。整个密码学界都认为SHA-1的抗碰撞能力非常重要。这种几乎被破坏的抗碰撞性会导致SHA-1的不安全调用。
    • 根据泄露的电子邮件,IOTA开发人员使用curl-p来处理关键的安全应用程序,但并不认为有必要将其提交给密码学专家的同行进行评审。用他们自己的话来说,他们觉得确保自制的加密技术安全性的唯一方法就是在生产系统中使用它然后看它是否受到攻击。
    • 根据DCI实验室的数据,对curl-p的攻击花费了20个小时。

    11. 但你确定真的有漏洞吗?

    根据密码学的定义,有漏洞。

    评估说curl-p不安全是因为它在生产系统中发挥着关键的安全作用(意味着它应该是一个加密哈希函数),但是它已经破坏了抗碰撞性(它不是一个安全的加密哈希函数)。

    评估认为在交易的数字签名方案中存在漏洞是因为有不安全的哈希函数,它意味着你可以使用以前交易的签名来伪造交易。

    12. 但你说这是密码学的定义……

    更严格地说,DCI实验室表明,根据EU-CMA,IOTA使用curl-p的交易数字签名方案失败了。在这种攻击中,攻击者能够签署他们选定的任何消息,并可以根据需要重复生成和签署消息。如果任意两条消息生成相同的签名,则攻击成功。

    对于此次攻击,消息来源是未签名的IOTA交易。由于交易的签名实际上是交易数据的curl-p哈希函数的签名,因此打破curl-p的抗碰撞性就足以赢得这场游戏。DCI实验室的研究人员通过产生碰撞消息打破了curl-p的抗碰撞性。这些碰撞消息是良构事务,这是一个额外收获。

    但是IOTA反驳说,EU-CMA的安全也被破坏了……

    相信我,我们现在都已经习惯了。

    泄露的电子邮件中,Sergey反驳了这一说法,理由是对EU-CMA安全的定义过于抽象。(这就是他提到的“真空中的球形签名方案”。)他的观点十分令人困惑,部分原因是他反复引用维基百科(Wikipedia)和security.stackexchange.com等网站上的非正式信息来为自己的观点辩护,他认为这些信息具有权威性。Sergey反复引用安全的定义,但是不考虑加密货币协议。其他时候,他对EU-CMA安全的定义提出异议,称其需要进行原像攻击。在推特上,他经常挑战那些认为IOTA很容易受到原像攻击的人,Heilman反复强调,这对于他们所概述的EU-CMA攻击来说不是必要的。

    Sergey在一篇文章中更仔细地阐述了他的理解。很明显,他的理解力还很差劲。他努力地从一个非常直截了当的角度来看待EU-CMA安全的各个方面。例如,EU-CMA允许攻击者获取从目标生成的任何消息的签名。因此,DCI实验室通过使用由他们控制的私钥来模拟提供这些消息的受害者。Sergey认为这违规了,因为他们模拟的是可以创建密钥的虚拟受害者,而不是无法创建密钥的虚拟受害者。

    Sergey也误解了“微不足道”这个词的概念。他一再强调,如果DCI实验室不提供在curl-p中查找碰撞的代码,那么他们就没有任何可信度,就好像这改变了curl-p在普通硬件上存在碰撞的事实,意味着碰撞对密码学者来说是微不足道的。

    Sergey并不是提出几个问题而已,而是在质疑密码学中他所能质疑的一切。如果他不理解这些概念,他应该去上与密码学相关的课程,在课堂上提出自己的问题,而不是去骚扰撰写漏洞报告的安全研究人员。如果做不到这一点,他应该聘请密码学专家来回答他的问题,因为他要求的细节如此之多,以至于DCI实验室能够主动满足其要求变得遥遥无期。

    13. 结论

    DCI实验室对IOTA存在漏洞的评估与密码学的定义一致。每一位密码学家、安全研究员和主要加密货币的开发者都公开发表了言论,他们都同意DCI实验室的观点。

    IOTA对此提出异议的原因如下:

    • 他们缺乏对密码学的功能性理解,以至于将security.stackexchange.com上的的非正式答案作为严格的定义;
    • 他们缺乏研究安全问题的直觉,以至于在没有同行评审的情况下,他们就开始使用自己的加密原语并在生产系统上进行测试;
    • 他们缺乏社会技能,无法准确解释密码学定义中更定性的方面,比如“微不足道”这个词的含义。
    作者:吴烦恼 | Categories:安全研究 | Tags:
  • Adobe ColdFusion RCE(CVE-2019-7839) 漏洞分析

    2019-08-21

    作者: Badcode@知道创宇404实验室 
    日期: 2019/07/09 
    英文版本: https://paper.seebug.org/1000/

    漏洞简介

    ​ Adobe ColdFusion 是一个商用的快速开发平台。它可以作为一个开发平台使用,也可以提供Flash远程服务或者作为 Adobe Flex应用的后台服务器 。

    ​ 2019年06月11日,Adobe 发布安全公告,修复了Adobe ColdFusion多个严重漏洞。其中有一个由Moritz Bechler提交的命令注入漏洞(CVE-2019-7839)。 ​ 2019年06月26日,Moritz Bechler 在 Bugtraq 上公布了远程代码执行漏洞(CVE-2019-7839)的部分细节,由于 JNBridge 组件存在缺陷,而 ColdFusion 默认开启JNBridge组件,导致代码执行漏洞。

    漏洞影响

    • ColdFusion 2018 Update 3 及之前的版本
    • ColdFusion 2018 Update 10 及之前的版本
    • ColdFusion 11 Update 18 及之前的版本
    • <= ColdFusion 9

    漏洞分析

    根据 Moritz Bechler 披露的部分细节,是由于ColdFusion 默认开启了 JNBridge listener 从而导致了漏洞。

    先来了解一下JNBridge。

    什么是 JNBridge?

    JNBridge 是一种领先的JAVA与.NET互操作的的产品,凭借JNBridge技术,Java 和.NET代码无需交叉编译器就可以实现对象共享。所有Java代码运行在JVM上,而.NET代码则运行在CLR上。在该方案下,JVM和CLR可以运 行在不同的机器上,也可以运行在一台机器的不同进程上,甚至还能运行在相同的进程的不同应用程序域上。

    下载 JNBridgePro,安装完之后会有demo。试用license

    这里我们尝试使用.net去调用java,跑一下logDemo,了解下大致流程。

    启动 Java 服务端

    根据 JNBridge 的安装路径,修改startJava.bat,运行

    可以看到,JNBridge 服务端 listener 已开启,监听在8085端口。

    构建 .Net 客户端

    根据 demo的指示文档 logDemo.pdf,一步一步构建 .Net 项目。

    运行

    运行 .Net 项目,调用 Java 服务端,成功调用。

    如何执行调用 java.lang.Runtime

    之前流程有一步是将 loggerDemo.javaClass转成 logger.dll,试想一下,是否可以将java.lang.Runtime导成dll文件,供 .Net 客户端引用,然后去调用 Java 服务端的java.lang.Runtime

    尝试一下

    将 rt.jar引入 classpath

    添加 java.lang.Runtime

    导出 runtime.dll

    引入 .Net 项目中供调用

    运行

    成功调用到了 Java 服务端中的java.lang.Runtime,这也是这个漏洞的根源。

    ColdFusion 中的 JNBridge

    ColdFusion 中是默认运行了 JNBridge listener 的,并且是 Java 服务端,监听端口是 6095(ColdFusion 2018)、6093(ColdFusion 2016)、6085(ColdFusion <=9/11)。

    由于 Coldfusion 中带的 JNBridge 版本不同,所以构造 payload 的方式有些差异。

    ColdFusion 2016/2018

    ColdFusion 2018 中的 JNBridge 版本是 v7.3.1,无法使用上面的的JNBridge v10去构造 payload,在 JNBridge 官网上可以下载一部分历史版本,下载 v7.3版本。

    编写想要在 Java 服务端执行的代码

    里面使用到了java.lang.Runtimejava.lang.Processjava.io.BufferedReaderjava.io.InputStreamReaderjava.lang.System,将相关类从rt.jar中导成runtime2.dll,供 .Net 客户端引用。

    根据 Java代码重写

    这里面有个非常重要的 JNBShare.dll,这里使用自己安装的 JNBridge 成功后生成的 JNBShare.dll,无法使用ColdFusion 中 JNBridge 的 JNBShare.dll,会报错。

    运行,攻击远程的ColdFusion 2018(Linux平台),成功返回结果。

    ColdFusion 9/11

    ColdFusion 9 内部的 JNBridge 版本是 v5.1,监听端口是 6085。由于这个版本比较老了,没找到安装包,现在需要生成供我们引用的runtime2.dll和能用的JNBShare.dll。ColdFusion 内部的 JNBridge中的jnbproxyGui.exe无法构建 .net -> java项目,也就是说GUI工具用不了,所幸的是命令行工具还可以用。

    jnbproxy.exe,看下参数。

    根据参数,生成runtime2.dll

    至于 JNBShare.dll,因为内部的无法使用,安装包又下载不到。幸运的是有人收藏了这个JNBShare.dll,谷歌搜索能够找到,并且刚好是v5.1版本的。

    运行,攻击远程的 ColdFusion 9(windows平台),返回命令执行结果。


    Paper

    本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/999/

    作者:吴烦恼 | Categories:安全研究 | Tags:
  • TSec 2019 议题 PPT:Comprehensive analysis of the mysql client attack chain

    2019-08-21

    作者:LoRexxar'@知道创宇404实验室

    2019年7月31日,以“前沿科技、尖端对抗”为主题的腾讯安全探索论坛(TSec)正式迎来第三届,知道创宇404实验室安全研究员@LoRexxar' 在大会上分享了议题《Comprehensive analysis of the mysql client attack chain》,从 Mysql 客户端攻击出发,探索真实世界攻击链。

    整个 PPT 我们将一起探讨关于 Mysql Client attack 的细节以及利用方式,在mysql任意文件读取的基础上,探讨并验证一些实际的攻击场景。其中包括 mysql 蜜罐溯源、mysql 探针、云服务 rds 服务,excel 数据同步服务以及一些cms的具体利用。

    在这些基础上,我们提出在 2018 年 Blackhat 大会上 Sam Thomas 分享的 File Operation Induced Unserialization via the “phar://” Stream Wrapper 议题中,曾提到 php 的文件读取函数读取 phar 协议会导致反序列化,在这个漏洞的基础上,我们可以把 php-mysqli 环境下的任意文件读取转为反序列化漏洞,在这个基础上,我们进一步讨论这个漏洞在cms通用环境下的普适性。

    议题PPT下载:https://github.com/knownsec/404-Team-ShowCase

    注:PPT中关于漏洞的具体详情已作删除处理,我们将会在推进负责的漏洞报送过程之后公开详细的漏洞分析文章。

    作者:吴烦恼 | Categories:安全研究 | Tags:
  • Typo3 CVE-2019-12747 反序列化漏洞分析

    2019-08-01

    作者:mengchen@知道创宇404实验室
    时间:2019年8月1日
    英文版本:https://paper.seebug.org/997/

    1. 前言

    TYPO3是一个以PHP编写、采用GNU通用公共许可证的自由、开源的内容管理系统。

    2019年7月16日,RIPS的研究团队公开了Typo3 CMS的一个关键漏洞详情CVE编号为CVE-2019-12747,它允许后台用户执行任意PHP代码。

    漏洞影响范围:Typo3 8.x-8.7.26 9.x-9.5.7

    2. 测试环境简述

     

    3. TCA

    在进行分析之前,我们需要了解下Typo3TCA(Table Configuration Array),在Typo3的代码中,它表示为$GLOBALS['TCA']

    Typo3中,TCA算是对于数据库表的定义的扩展,定义了哪些表可以在Typo3的后端可以被编辑,主要的功能有

    • 表示表与表之间的关系
    • 定义后端显示的字段和布局
    • 验证字段的方式

    这次漏洞的两个利用点分别出在了CoreEngineFormEngine这两大结构中,而TCA就是这两者之间的桥梁,告诉两个核心结构该如何表现表、字段和关系。

    TCA的第一层是表名:

     

    其中pagestt_content就是数据库中的表。

    接下来一层就是一个数组,它定义了如何处理表,

     

    在这次分析过程中,只需要了解这么多,更多详细的资料可以查询官方手册

    4. 漏洞分析

    整个漏洞的利用流程并不是特别复杂,主要需要两个步骤,第一步变量覆盖后导致反序列化的输入可控,第二步构造特殊的反序列化字符串来写shell。第二步这个就是老套路了,找个在魔术方法中能写文件的类就行。这个漏洞好玩的地方在于变量覆盖这一步,而且进入两个组件漏洞点的传入方式也有着些许不同,接下来让我们看一看这个漏洞吧。

    4.1 补丁分析

    从Typo3官方的通告中我们可以知道漏洞影响了两个组件——Backend & Core API (ext:backend, ext:core),在GitHub上我们可以找到修复记录

    很明显,补丁分别禁用了backendDatabaseLanguageRows.phpcore中的DataHandler.php中的的反序列化操作。

    4.2 Backend ext 漏洞点利用过程分析

    根据补丁的位置,看下Backend组件中的漏洞点。

    路径:typo3/sysext/backend/Classes/Form/FormDataProvider/DatabaseLanguageRows.php:37

     

    很多类都继承了FormDataProviderInterface接口,因此静态分析寻找谁调用的DatabaseLanguageRowsaddData方法根本不现实,但是根据文章中的演示视频,我们可以知道网站中修改page这个功能中进入了漏洞点。在addData方法加上断点,然后发出一个正常的修改page的请求。

    当程序断在DatabaseLanguageRowsaddData方法后,我们就可以得到调用链。

    DatabaseLanguageRows这个addData中,只传入了一个$result数组,而且进行反序列化操作的目标是$result['databaseRow']中的某个值。看命名有可能是从数据库中获得的值,往前分析一下。

    进入OrderedProviderListcompile方法。

    路径:typo3/sysext/backend/Classes/Form/FormDataGroup/OrderedProviderList.php:43

     

    我们可以看到,在foreach这个循环中,动态实例化$this->providerList中的类,然后调用它的addData方法,并将$result作为方法的参数。

    在调用DatabaseLanguageRows之前,调用了如图所示的类的addData方法。

    经过查询手册以及分析代码,可以知道在DatabaseEditRow类中,通过调用addData方法,将数据库表中数据读取出来,存储到了$result['databaseRow']中。

    路径:typo3/sysext/backend/Classes/Form/FormDataProvider/DatabaseEditRow.php:32

     

    再后面又调用了DatabaseRecordOverrideValues类的addData方法。

    路径:typo3/sysext/backend/Classes/Form/FormDataProvider/DatabaseRecordOverrideValues.php:31

     

    在这里,将$result['overrideValues']中的键值对存储到了$result['databaseRow']中,如果$result['overrideValues']可控,那么通过这个类,我们就能控制$result['databaseRow']的值了。

    再往前,看看$result的值是怎么来的。

    路径:typo3/sysext/backend/Classes/Form/FormDataCompiler.php:58

     

    很明显,通过调用FormDataCompilercompile方法,将$initialData中的数据存储到了$result中。

    再往前走,来到了EditDocumentController类中的makeEditForm方法中。

    在这里,$formDataCompilerInput['overrideValues']获取了$this->overrideVals[$table]中的数据。

    $this->overrideVals的值是在方法preInit中设定的,获取的是通过POST传入的表单中的键值对。

    这样一来,在这个请求过程中,进行反序列化的字符串我们就可以控制了。

    在表单中提交任意符合数组格式的输入,在后端代码中都会被解析,然后后端根据TCA来进行判断并处理。 比如我们在提交表单中新增一个名为a[b][c][d],值为233的表单项。

    在编辑表单的控制器EditDocumentController.php中下一个断点,提交之后。

    可以看到我们传入的键值对在经过getParsedBody方法解析后,变成了嵌套的数组,并且没有任何限制。

    我们只需要在表单中传入overrideVals这一个数组即可。这个数组中的具体的键值对,则需要看进行反序列化时取的$result['databaseRow']中的哪一个键值。

     

    要想进入反序列化的点,还需要满足上面的if条件,动态调一下就可以知道,在if语句中调用的是

     

    后面反序列化中调用的是

    因此,我们只需要在传入的表单中增加三个参数即可。

     

    可以看到,我们的输入成功的到达了反序列化的点。

    4.3 Core ext 漏洞点利用过程分析

    看下Core中的那个漏洞点。

    路径:typo3/sysext/core/Classes/DataHandling/DataHandler.php:1453

    看代码,如果我们要进入反序列化的点,需要满足前面的if条件

     

    也就是说要满足以下条件

    • $currentRecord是个数组
    • TCA$table的表属性中存在transOrigDiffSourceFieldlanguageFieldtransOrigPointerField字段。
    • $table的属性languageFieldtransOrigPointerField$currentRecord中对应的值要大于0

    查一下TCA表,满足第二条条件的表有

     

    但是所有sys_*的字段的adminOnly属性的值都是1,只有管理员权限才可以更改。因此我们可以用的表只有pages

    它的属性值是

     

    再往上,有一个对传入的参数进行处理的if-else语句。

    从注释中,我们可以知道传入的各个参数的功能:

    • 数组 $fieldArray 是默认值,这种一般都是我们无法控制的
    • 数组 $incomingFieldArray 是你想要设置的字段值,如果可以,它会合并到$fieldArray中。

    而且如果满足if (strpos($id, 'NEW') !== false)条件的话,也就是$id是一个字符串且其中存在NEW字符串,会进入下面的合并操作。

    如果不满足上面的if条件,$currentRecord的值就会通过recordInfo方法从数据库中直接获取。这样后面我们就无法利用了。

    简单总结一下,我们需要

    • $tablepages
    • $id是个字符串,而且存在NEW字符串
    • $incomingFieldArray中要存在payload

    接下来我们看在哪里对该函数进行了调用。

    全局搜索一下,只找到一处,在typo3/sysext/core/Classes/DataHandling/DataHandler.php:954处的process_datamap方法中进行了调用。

    整个项目中,对process_datamap调用的地方就太多了,尝试使用xdebug动态调试来找一下调用链。从RIPS团队的那一篇分析文章结合上面的对表名的分析,我们可以知道,漏洞点在创建page的功能处。

    接下来就是找从EditDocumentController.phpmainAction方法到前面我们分析的fillInFieldArray方法的调用链。

    尝试在网站中新建一个page,然后在调用fillInFieldArray的位置下一个断点,发送请求后,我们就拿到了调用链。

    看一下mainAction的代码。

     

    当满足if条件是进入目标$response = $this->processData($request)

     

    这个在新建一个page时,正常的表单中就携带doSave == 1,而doSave的值就是在方法preInit中获取的。

    这样条件默认就是成立的,然后将$request传入了processData方法。

     

    代码很容易懂,从$request中解析出来的数据,首先存储在$this->data$this->cmd中,然后实例化一个名为$tce,调用$tce->start方法将传入的数据存储在其自身的成员datamapcmdmap中。

     

    而且if ($this->doSave === true)这个条件也是成立的,进入process_datamap方法。

    代码有注释还是容易阅读的,在第985行,获取了datamap中所有的键名,然后存储在$orderOfTables,然后进入foreach循环,而这个$table,在后面传入fillInFieldArray方法中,因此,我们只需要分析$table == pages时的循环即可。

     

    大致浏览下代码,再结合前面的分析,我们需要满足以下条件:

    • $recordAccess的值要为true
    • $incomingFieldArray中的payload不会被删除
    • $table的值为pages
    • $id中存在NEW字符串

    既然正常请求可以直接断在调用fillInFieldArray处,正常请求中,第一条、第三条和第四条都是成立的。

    根据前面对fillInFieldArray方法的分析,构造payload,向提交的表单中添加三个键值对。

     

    其中NEW*字符串要根据表单生成的值进行对应的修改。

    发送请求后,依旧能够进入fillInFieldArray,而在传入的$incomingFieldArray参数中,可以看到我们添加的三个键值对。

    进入fillInFieldArray之后,其中l10n_diffsource将会进行反序列化操作。此时我们在请求中将其l10n_diffsource改为构造好的序列化字符串,重新发送请求即可成功getshell

    5. 写在最后

    其实单看这个漏洞的利用条件,还是有点鸡肋的,需要你获取到typo3的一个有效的后台账户,并且拥有编辑page的权限。

    而且这次分析Typo3给我的感觉与其他网站完全不同,我在分析创建&修改page这个功能的参数过程中,并没有发现什么过滤操作,在后台的所有参数都是根据TCA的定义来进行相应的操作,只有传入不符合TCA定义的才会抛出异常。而TCA的验证又不严格导致了变量覆盖这个问题。

    官方的修补方式也是不太懂,直接禁止了反序列化操作,但是个人认为这次漏洞的重点还是在于前面变量覆盖的问题上,尤其是Backend的利用过程中,可以直接覆盖从数据库中取出的数据,这样只能算是治标不治本,后面还是有可能产生新的问题。

    当然了,以上只是个人拙见,如有错误,还请诸位斧正。

    6. 参考链接

    作者:吴烦恼 | Categories:安全研究 | Tags:
  • CVE-2019-11229详细分析 –git config可控-RCE

    2019-07-24

    作者:LoRexxar'@知道创宇404实验室
    时间:2019年7月23日
    英文版本:https://paper.seebug.org/990/

    2019年4月15号,gitea曾爆出过一个漏洞,恰逢当时对这个漏洞比较好奇就着手去研究了一下,漏洞的描述是这样的:

    models/repo_mirror.go in Gitea before 1.7.6 and 1.8.x before 1.8-RC3 mishandles mirror repo URL settings, leading to remote code execution.

    在和朋友@hammer的一同研究下,成功控制了git config的内容,但是在从git config到RCE的过程遇到了困难,就暂时搁置了,在过了几个月之后,偶然得到@Lz1y和@x1nGuang两位大佬的启发,成功复现了这个漏洞,下面我们就来仔细研究下这个问题。

    分析补丁

    首先根据cve的信息,确定漏洞1.7.6和1.8.0-rc3上修复

    根据漏洞文件为repo_mirror.go这个信息锁定更新的commit,commit主要为 #6593和#6595

    根据patch可以大致锁定问题的关键点

    /models/repo_mirror.go

    当仓库为mirror仓库时,settings页面会显示关于mirror的配置

    patch中将原来的修改配置文件中的url选项修改为NewCommand。很容易理解,将写入文件更改为执行命令,这种修复方式一定是因为写入文件存在无法修复这个问题的窘境,那么这也就说明url这里可以通过传入%0d%0a来换行,导致修改config中的其他配置。

    控制 gitconfig

    跟随前面的逻辑,首先我们新建一个mirror仓库。

    抓包并修改mirror_address为相应的属性。

    可以传入各种配置,可以控制config文件的内容。

    比较有趣的是,如果你更新同步设置时,服务端还会格式化配置。

    进一步利用

    而重要的是如何从config文件可控到下一步利用。

    首先,git服务端只会保留.git里的内容,并不是完整的类似我们客户端使用的git仓库。所以很难引入外部文件。否则就可以通过设置hook目录来实现RCE,这种思路的关键点在于找到一个可控的文件写入或者文件上传。

    其次,另外一种思路就是寻找一个能够执行命令的配置,并寻找一个能够触发相关配置的远程配置。

    通过写文件配合 githook path RCE

    在git中,存在一个叫做Git Hook的东西,是用于在处理一些操作的时,相应的hook就会执行相应的脚本。

    在web界面,只有gitea的管理员才能管理git hook,所以对于普通用户来说,我们就不能直接通过编辑git hook来修改脚本。

    但我们却可以通过控制git config来修改hook存放的目录。

    当我们构造发送

    服务端的config文件变为

    这样我们只要能在服务端的任意位置能够写入文件或者创建文件,我们就可以设置hookspath到那里,并触发git hook来执行命令。

    在经过我们的仔细研究之后,我们发现,在漏洞存在的版本1.7.5版本以下,如果编辑服务端的文件,那么服务端的文件就会保存在gitea的运行目录下生成。

    而这个文件在不重启gitea的情况下不会清除,而这个repo_id可以从其他的api处挖掘到。

    具体详细利用链可以看

    值得注意的是,这种方式需要知道服务端运行的位置,虽然我们可以认为go的路径都是比较形似的,也有部分人会在当前编译目录下执行。但可以说这种方式还是不算靠谱。

    通过控制 git config 配置来 RCE

    在@x1nGuang大佬的帮助下,我重新审视了和git config相关的一些配置。

    gitProxy

    gitProxy是用来针对git协议需要fetch等操作时,需要执行的命令。是一个用来应对特殊场景的配置选项。一般是应用于,在git请求时,可能的需要使用代理应用的场景。

    这里我们设置服务端

    然后需要注意,同步的url必须为git开头

    但问题在于,由于gitProxy在git设计中,就是执行一个代理应用,所以无论输入什么,都会被当作一个应用执行,也就没办法带参数。

    这样一来,在实际的利用场景中就又受到了很大的局限,这里可以尝试用普通项目中的上传文件功能来上传一个bin,然后抓包获取文件路径,最后通过gitProxy来执行后门。

    但同样的是,这种思路仍旧受限于gitea的运行目录,不过比起之前的利用方式来说,1.8.0版本也可以利用这种方式来RCE。

    sshCommand

    在git的文档中,还有一个配置是sshCommand。

    这是一个在git中允许通过特殊的配置,使git fetch/git push 通过ssh来连接远端的系统。在@Lz1y大佬的博客中也提到了这种利用方式。

    我们设置sshCommand为指定的命令

    然后设置协议为ssh保存,并点击同步。

    而与gitProxy不同的是,这里可以跟参数

    写在最后

    这是一个很特别的关于git类平台的漏洞例子,由于我在研究git config利用方式的时候遭遇了很多困难,导致这篇文章断断续续的复现了很久。整个漏洞利用链和git的特性都有强依赖,还算是挺有趣的体验,有机会再仔细分析一下gitea、gogs和gitlab的代码,希望也能挖一个有趣的洞...


    Paper

    本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/989/

    作者:吴烦恼 | Categories:安全研究 | Tags:
  • Redis 基于主从复制的 RCE 利用方式

    2019-07-15

    作者:LoRexxar'@知道创宇404实验室
    时间:2019年7月9日

    在2019年7月7日结束的WCTF2019 Final上,LC/BC的成员Pavel Toporkov在分享会上介绍了一种关于redis新版本的RCE利用方式,比起以前的利用方式来说,这种利用方式更为通用,危害也更大,下面就让我们从以前的redis RCE利用方式出发,一起聊聊关于redis的利用问题。

    https://2018.zeronights.ru/wp-content/uploads/materials/15-redis-post-exploitation.pdf

    通过写入文件 GetShell

    未授权的redis会导致GetShell,可以说已经是众所周知的了。

    而这种方式是通过写文件来完成GetShell的,这种方式的主要问题在于,redis保存的数据并不是简单的json或者是csv,所以写入的文件都会有大量的无用数据,形似

    这种主要利用了crontab、ssh key、webshell这样的文件都有一定容错性,再加上crontab和ssh服务可以说是服务器的标准的服务,所以在以前,这种通过写入文件的getshell方式基本就可以说是很通杀了。

    但随着现代的服务部署方式的不断发展,组件化成了不可逃避的大趋势,docker就是这股风潮下的产物之一,而在这种部署模式下,一个单一的容器中不会有除redis以外的任何服务存在,包括ssh和crontab,再加上权限的严格控制,只靠写文件就很难再getshell了,在这种情况下,我们就需要其他的利用手段了。

    通过主从复制 GetShell

    在介绍这种利用方式之前,首先我们需要介绍一下什么是主从复制和redis的模块。

    Redis主从复制

    Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。但如果当把数据存储在单个Redis的实例中,当读写体量比较大的时候,服务端就很难承受。为了应对这种情况,Redis就提供了主从模式,主从模式就是指使用一个redis实例作为主机,其他实例都作为备份机,其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。

    这里我们开两台docker来做测试

    然后通过slaveof可以设置主从状态

    这样一来数据就会自动同步了

    Redis模块

    在了解了主从同步之后,我们还需要对redis的模块有所了解。

    在Reids 4.x之后,Redis新增了模块功能,通过外部拓展,可以实现在redis中实现一个新的Redis命令,通过写c语言并编译出.so文件。

    编写恶意so文件的代码

    https://github.com/RicterZ/RedisModules-ExecuteCommand

    利用原理

    Pavel Toporkov在2018年的zeronights会议上,分享了关于这个漏洞的详细原理。

    https://2018.zeronights.ru/wp-content/uploads/materials/15-redis-post-exploitation.pdf

    在ppt中提到,在两个Redis实例设置主从模式的时候,Redis的主机实例可以通过FULLRESYNC同步文件到从机上。

    然后在从机上加载so文件,我们就可以执行拓展的新命令了。

    复现过程

    这里我们选择使用模拟的恶意服务端来作为主机,并模拟fullresync请求。

    https://github.com/LoRexxar/redis-rogue-server

    然后启用redis 5.0的docker

    为了能够更清晰的看到效果,这里我们把从服务端执行完成后删除的部分暂时注释掉。

    然后直接通过脚本来攻击服务端

    然后我们链接上去就可以执行命令

     

    Paper

    本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/975/

    作者:吴烦恼 | Categories:安全研究技术分享 | Tags: