freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Coinhive挖矿脚本分析与Pool改造自建(一)
2017-10-20 17:33:16

抱歉,忘记此篇已经投稿到先知,希望主编大大高抬贵手,帮我修改成普通文章,第二篇将如期发布,尽情期待~

引言

虽然“前端挖矿脚本”是近一个月才从业内报告中进入公众视野的词汇但在“一棒子打死”型各大媒体站的“详细分析”下我看到满是“黑客恶意植入”、“占用CPU”、“非法牟利”等负面评价的所谓“分析”和传说中的可笑“查杀检查方法”鲜有对此技术从各层面分析和冷静判断的文章或者新闻这么好一个转换流量变现或者说用来进行机器人验证的“硬算力”方式却被直接贴上“非法”标签对于做技术和饱含极客精神的人们真是不友好。。

于是你现在看到的就是我这个“为前端技术和匿名算法叫冤”的“和事老”从一个更有趣的角度以较为通俗的语言、尽量全面的解析、外加合理改造和白利用姿势用来“科普”的一篇赚稿费的“水文”。

词汇解释

区块链分布式数据存储、P2P传输、共识机制、加密算法等计算机技术的新型应用模式。其中共识机制指区块链系统中实现不同节点之间建立信任、获取权益的数学算法。理解为你工作的绩效评定方法

钱包用来记录个人用户电子货币资产、操作交易、用于收发货币的一个"hash"地址。理解为汇款地址或者你的工资卡吧

矿池相关电子货币根据区块链同一分配“生产”任务的发布平台同时也是算力效验的对接平台。理解为你的工作单位

挖矿此处指利用设备算力按特定电子货币生产计算方法和矿池分配方式产生的经济价值。理解为努力工作的这个行为

前端挖矿从挖矿技术来说是没有前后端的此处前端也是指的浏览器前端而本文前端挖矿就是说“浏览器内实现、通过用户访问实施挖矿”的一种方式。理解成工作偷懒让别人干活的方式吧 ⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄

抱歉如果文章里还有不懂却未提到的请自行网上查询

概念分析

在进入正题的时候我们必须理解一个概念那就是正常挖矿和前端挖矿的区别技术以及意义。

金镐子银镐子挖矿方便才是好镐子 :)

区别

一般挖矿用户以主动方式直接使用C或者其他语言构造的miner客户端进行CPU或GPU计算得到算力价值。

前端挖矿用户以被动或主动方式在不知情或知情情况下由浏览者产生的CPU或GPU计算得到算力价值。

技术

一般挖矿利用CPU或GPU本身的高速浮点计算能力进行挖矿工作。而一般挖矿选取有更优秀浮点计算能力的GPU进行操作。

前端挖矿利用asm.js或webAssembly前端解析器中介在浏览器端被动使用用户的CPU完成挖矿或者利用Html5新规范WebGL利用浏览器完成GPU挖矿操作。

意义

一般挖矿: 从行为和实现方式看是一种主动在自己设备完成的挖矿行为排除非法控制他人设备情况c实现的工具直接使用OS的底层驱动和接口无论操作内存、CPU或GPU流程损耗低计算速度更快。

前端挖矿: 从行为和实现方式看可以是一种以被动方式在其他用户浏览到某网页情况下在非己设备上发生的挖矿行为通过将算力任务分担给其他浏览用户来实现“分布式”计算其实更应该叫利用多设备优势提高单一时间内单目标多任务并发能力

Coinhive脚本分析

关键字 WebSocket / worker / asm.js / WebAssembly

传送门coinhive.min.js

https://coinhive.com/lib/
.
|—— coinhive.min.js                            // wss矿池通信分配worker交互实现
|   :.. (CoinHive.CONFIG.WEBSOCKET_SHARDS)     // WebSocket地址连接pool进行任务发布等功能
|   :.. (CoinHive.CRYPTONIGHT_WORKER_BLOB)     // 以CreateURL形式动态生成Blob链接对worker内容实现
|—— cryptonight.wasm                           // WebAssembly实现预计源cryptonight.c & keccak.c 等
|—— cryptonight-asmjs.min.js                   // 兼容方案asmjs实现内容worker除外从L4851算法开始
|__ cryptonight-asmjs.min.js.mem               // 浏览器中asmjs所需模拟内存实现

通过阅读脚本可以在Blob构造的worker实例下文中称worker.js看到如下对运行平台的判断

worker.js ( L21 .. L50 )

var Module;
if (!Module) Module = (typeof Module !== "undefined" ? Module : null) || {};
var moduleOverrides = {};
for (var key in Module) {
    if (Module.hasOwnProperty(key)) {
        moduleOverrides[key] = Module[key]
    }
}
var ENVIRONMENT_IS_WEB = false;
var ENVIRONMENT_IS_WORKER = false;
var ENVIRONMENT_IS_NODE = false;
var ENVIRONMENT_IS_SHELL = false;
if (Module["ENVIRONMENT"]) {
    if (Module["ENVIRONMENT"] === "WEB") {
        ENVIRONMENT_IS_WEB = true
    } else if (Module["ENVIRONMENT"] === "WORKER") {
        ENVIRONMENT_IS_WORKER = true
    } else if (Module["ENVIRONMENT"] === "NODE") {
        ENVIRONMENT_IS_NODE = true
    } else if (Module["ENVIRONMENT"] === "SHELL") {
        ENVIRONMENT_IS_SHELL = true
    } else {
        throw new Error("The provided Module['ENVIRONMENT'] value is not valid. It must be one of: WEB|WORKER|NODE|SHELL.")
    }
} else {
    ENVIRONMENT_IS_WEB = typeof window === "object";
    ENVIRONMENT_IS_WORKER = typeof importScripts === "function";
    ENVIRONMENT_IS_NODE = typeof process === "object" && typeof require === "function" && !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_WORKER;
    ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER
}

看来其实coinhive支持包括本地挖矿的其他兼容方式野心不小呀。

再来看实现过程对兼容性的处理:

worker.js ( L1169 .. L1179 )

function integrateWasmJS(Module) {
    var method = Module["wasmJSMethod"] || "native-wasm";
    Module["wasmJSMethod"] = method;
    var wasmTextFile = Module["wasmTextFile"] || "cryptonight.wast";
    var wasmBinaryFile = Module["wasmBinaryFile"] || "cryptonight.wasm";
    var asmjsCodeFile = Module["asmjsCodeFile"] || "cryptonight.temp.asm.js";
    if (typeof Module["locateFile"] === "function") {
        wasmTextFile = Module["locateFile"](wasmTextFile);
        wasmBinaryFile = Module["locateFile"](wasmBinaryFile);
        asmjsCodeFile = Module["locateFile"](asmjsCodeFile)
    }

从容地概括本地挖矿和浏览器内前端挖矿并对不同浏览器对WebAssembly的支持情况进行兼容。

cryptonight.wasm & cryptonight-asmjs.min.js

我知道怎么从file.c转化成file.wasm或者file.asm.js但是你让我挑出来给你分析这俩文件的内容

你自己去下下来看看你就知道为什么本文不做分析了…… :)

但是如果非要问我可以告诉你文件主要就是cryptonight算法的实现和一般Miner并无两样只是参数传入传出方式由前端方式二次构造。

目测来源项目ccminer 或 stak CPU miner

example1 https://github.com/tsiv/ccminer-cryptonight/tree/master/crypto

example2 https://github.com/jquesnelle/xmr-stak-cpu/tree/master/crypto

对于worker队列内的一些实现你也可以跟我一起过一遍他们的代码目前看来虽然并未提起开源但也还不是webpack打包的js函数名没有替换流程也相对清晰一步步看下来你也能说出个大概。

听人千言不如亲眼所见一定要养成强迫自己阅读别人代码并记录他人书写中优美片段的好习惯。

如果你还非得要我分析算法构成真巧我研究的时候顺便翻译了一下CryptoNight的白皮书Mark在Freebuf今后自己回头来学习。

CryptoNight 文档

概要

CryptoNote Standards 介绍了一种点对点的匿名支付系统本文档是 CryptoNote Standards 的一部分定义了 CryptoNote 的缺省工作量证明散列函数CryptoNight。

版权及授权说明

版权所有c2013 CryptoNote。 本文档可在知识共享署名3.0许可证国际许可权限范围内查询。

许可副本 http://creativecommons.org/licenses/by/3.0/

目录

  1. 算法介绍
  2. 名词解释
  3. 初始化流程
  4. 内存处理流程
  5. 结果计算流程
  6. 参考内容

1.算法介绍

CryptoNight是一个使用物理内存的高强度hash算法函数。 它的设计适用于GPUFPGA和ASIC架构上的有效性算力。流程的第一步是初始化大型暂存器与伪随机数据下一步是算法对暂存器中包含伪随机地址的大量的读/写计算操作最后一步是将整个暂存器的hash值进行hash效验验证本次计算产生的价值。

2. 算法定义

hash函数映射数据的有效计算函数对于固定大小的数据、构造特定算法行为产生类似随机数结果

暂存器在算法过程中申请用于存储计算时中间值的部分内存

3. 初始化流程

首先使用参数 b = 1600c = 512 .对输入内容进行Keccak计算 [ KECCAK ]。计算结果的0..31字节用作AES-256密钥[AES]并扩展为10个循环密钥申请一个分配了2097152字节2 MB空间的暂存器从计算结果的64..191字节处提取出来数据并分割成8个块每个块16字节。使用以下步骤对每个块进行加密

for i = 0..9 do:
block = aes_round(block, round_keys[i])

aes_round() 函数执行一轮AES加密对本块执行 SubBytes ShiftRowsMixColumns 步骤其结果与round_key进行异或运算。但这不同于AES加密算法第一轮计算和最后一轮计算没什么不同。

一轮下来得到的计算结果写入暂存器的前128个字节然后这些结果再次代入加密循环再把这次循环结果写入暂存器的第二个128字节里。这里每次往暂存器里写入下一个128字节都代表对先前写入的128字节内容在新一轮加密的结果。流程一直循环直到暂存器写满。至此一次算法的初始化就完成了。

该图表示暂存器初始化

                               +-----+
                               |Input|
                               +-----+
                                  |
                                  V
                             +--------+
                             | Keccak |
                             +--------+
                                  |
                                  V
   +-------------------------------------------------------------+
   |                         Final state                         |
   +-------------+--------------+---------------+----------------+
   | Bytes 0..31 | Bytes 32..63 | Bytes 64..191 | Bytes 192..199 |
   +-------------+--------------+---------------+----------------+
          |                             |
          V                             |
   +-------------+                      V
   | Round key 0 |------------+---+->+-----+
   +-------------+            |   |  |     |
   |      .      |            |   |  |     |
   |      .      |            |   |  | AES |
   |      .      |            |   |  |     |
   +-------------+            |   |  |     |
   | Round key 9 |----------+-|-+-|->+-----+                 +---+
   +-------------+          | | | |     |                    |   |
                            | | | |     +------------------->|   |
                            | | | |     |                    |   |
                            | | | |     V                    |   |
                            | | | +->+-----+                 |   |
                            | | |    |     |                 | S |
                            | | |    |     |                 |   |
                            | | |    | AES |                 | c |
                            | | |    |     |                 |   |
                            | | |    |     |                 | r |
                            | | +--->+-----+                 |   |
                            | |         |                    | a |
                            | |         +------------------->|   |
                            | |         .                    | t |
                            | |         .                    |   |
                            | |         .                    | c |
                            | |         +------------------->|   |
                            | |         |                    | h |
                            | |         V                    |   |
                            | +----->+-----+                 | p |
                            |        |     |                 |   |
                            |        |     |                 | a |
                            |        | AES |                 |   |
                            |        |     |                 | d |
                            |        |     |                 |   |
                            +------->+-----+                 |   |
                                        |                    |   |
                                        +------------------->|   |
                                                             |   |
                                                             +---+

4. 内存处理流程

在主循环之前对输入内容进行Keccak计算后取0..31字节和32..63字节进行异或所得到的32字节结果用于初始化变量a和b分别各占16字节这两个变量将用于主循环主循环进行524,288次迭代当一个16字节值需要转换成暂存器中的一个地址将以低字节顺序压入内存21位低字节用作索引但是索引中的4个低字节将被清除以确保地址索引统一16字节对齐。 数据从16字节块中读取并写入暂存器。

迭代流程伪代码

scratchpad_address = to_scratchpad_address(a)
scratchpad[scratchpad_address] = aes_round(scratchpad [scratchpad_address], a)
b, scratchpad[scratchpad_address] = scratchpad[scratchpad_address],
    b xor scratchpad[scratchpad_address]
scratchpad_address = to_scratchpad_address(b)
a = 8byte_add(a, 8byte_mul(b, scratchpad[scratchpad_address]))
a, scratchpad[scratchpad_address] = a xor scratchpad[scratchpad_address], a

8byte_add() 函数将每个参数表示为一对64位低位值并将它们组合在一起以分量形式进行快速模除 2 ^ 64。 其结果返回16字节。

8byte_mul() 函数仅使用每个参数的前8个字节并分别解析为无符号64位低位字节整数并相乘。 其结果返回16字节最后结果分半两边的8字节相互交换。

内存处理流程图

   +-------------------------------------------------------------+
   |                         Final state                         |
   +-------------+--------------+---------------+----------------+
   | Bytes 0..31 | Bytes 32..63 | Bytes 64..191 | Bytes 192..199 |
   +-------------+--------------+---------------+----------------+
          |             |
          |   +-----+   |
          +-->| XOR |<--+
              +-----+
               |   |
          +----+   +----+
          |             |
          V             V
        +---+         +---+
        | a |         | b |
        +---+         +---+
          |             |
   --------------------- REPEAT 524288 TIMES ---------------------
          |             |                            address +---+
          +-------------|----------------------------------->|   |
          |   +-----+   |                               read |   |
          +-->| AES |<--|------------------------------------|   |
          |   +-----+   V                                    |   |
          |      |   +-----+                                 | S |
          |      +-->| XOR |                                 |   |
          |      |   +-----+                           write | c |
          |      |      |    +------------------------------>|   |
          |      |      +----+                       address | r |
          |      +------------------------------------------>|   |
          |      |  +-----------+                       read | a |
          |      +->| 8byte_mul |<--+------------------------|   |
          |      |  +-----------+   |                        | t |
          |      |        |         |                        |   |
          |      |        V         |                        | c |
          |      |  +-----------+   |                        |   |
          +------|->| 8byte_add |   |                        | h |
                 |  +-----------+   |                        |   |
                 |        |         |                  write | p |
                 |        +---------|----------------------->|   |
                 |        |         |                        | a |
                 |        V         |                        |   |
                 |     +-----+      |                        | d |
                 |     | XOR |<-----+                        |   |
                 |     +-----+                               |   |
                 +------+ |                                  |   |
          +-------------|-+                                  |   |
          |             |                                    +---+
   -------------------------- END REPEAT -------------------------
          |             |

5. 结果计算流程

在内存操作完成之后使用与第一步骤初始化步骤分相同的方式进行Keccak计算最终结果的32..63字节被扩展成10个AES循环密钥。

从Keccak结果里提取64..191字节并与暂存器里前128个字节进行异或运算。然后结果以与第一步初始化步骤使用相同的方式进行加密但是使用新的密钥。结果继续与暂存器中的第二个128个字节进行异或运算依次循环加密迭代。

在暂存器的最后128个字节进行异或运算后就是流程的最后一次加密完成后将原本Keccak结果的64..191字节内容替换为本次加密内容。然后以b = 1600对整个块内容进行Keccak-fKeccak排列。

然后结果中第一个字节的2个低位比特用于进行散列函数运算0 = BLAKE-256 [BLAKE]1 = Groestl-256 [GROESTL]2 = JH-256 [JH] 3 = Skein-256 [SKEIN]。最后将所选的散列函数应用于Keccak最终结果生成的散列就是CryptoNight算法的计算输出。

结果计算流程图

   +-------------------------------------------------------------+
   |                         Final state                         |
   +-------------+--------------+---------------+----------------+
   | Bytes 0..31 | Bytes 32..63 | Bytes 64..191 | Bytes 192..199 |
   +-------------+--------------+---------------+----------------+
         |                |             |                |
         |       +--------+             |                |
         |       V        |             |                |
         |+-------------+ |             |                |
         || Round key 0 |-|---+---+     |                |
         |+-------------+ |   |   |     |                |
         ||      .      | |   |   |     |                |
         ||      .      | |   |   |     |                |
         ||      .      | |   |   |     |                |
         |+-------------+ |   |   |     |                |
   +---+ || Round key 9 |-|-+-|-+ |     V                |
   |   | |+-------------+ | | | | |  +-----+             |
   |   |-|----------------|-|-|-|-|->| XOR |             |
   |   | |                | | | | |  +-----+             |
   | S | |                | | | | |     |                |
   |   | |                | | | | |     V                |
   | c | |                | | | | +->+-----+             |
   |   | |                | | | |    |     |             |
   | r | |                | | | |    |     |             |
   |   | |                | | | |    | AES |             |
   | a | |                | | | |    |     |             |
   |   | |                | | | |    |     |             |
   | t | |                | | | +--->+-----+             |
   |   | |                | | |         |                |
   | c | |                | | |         V                |
   |   | |                | | |      +-----+             |
   | h |-|----------------|-|-|----->| XOR |             |
   |   | |                | | |      +-----+             |
   | p | |                | | |         |                |
   |   | |                | | |         .                |
   | a | |                | | |         .                |
   |   | |                | | |         .                |
   | d | |                | | |         |                |
   |   | |                | | |         V                |
   |   | |                | | |      +-----+             |
   |   |-|----------------|-|-|----->| XOR |             |
   |   | |                | | |      +-----+             |
   +---+ |                | | |         |                |
         |                | | |         V                |
         |                | | +----->+-----+             |
         |                | |        |     |             |
         |                | |        |     |             |
         |                | |        | AES |             |
         |                | |        |     |             |
         |                | |        |     |             |
         |                | +------->+-----+             |
         |                |             |                |
         V                V             V                V
   +-------------+--------------+---------------+----------------+
   | Bytes 0..31 | Bytes 32..63 | Bytes 64..191 | Bytes 192..199 |
   +-------------+--------------+---------------+----------------+
   |                       Modified state                        |
   +-------------------------------------------------------------+
                                  |
                                  V
                            +----------+
                            | Keccak-f |
                            +----------+
                             |    |
                 +-----------+    |
                 |                |
                 V                V
          +-------------+  +-------------+
          | Select hash |->| Chosen hash |
          +-------------+  +-------------+
                                  |
                                  V
                          +--------------+
                          | Final result |
                          +--------------+

计算结果举例

    Empty string:
      eb14e8a833fac6fe9a43b57b336789c46ffe93f2868452240720607b14387e11.

    "This is a test":
      a084f01d1437a09c6985401b60d43554ae105802c5f5d8a9b3253649c0be6605.

白皮书里头涉及的算法在example里两个Miner项目中都有c实现。

可见此Coinhive脚本中XMR挖矿算法(cryptonight)就是靠一下任意一个形式实现的对C书写的算法的封装了。

  1. wasmBinaryFile => (cryptonight.wasm)

  2. asmjsCodeFile => (cryptonight-asmjs.min.js)

asm.jsWebAssembly 如何将C代码转为可执行的javascript文件抱歉这一下子根本就讲不清楚所以大家只需要知道这两项技术旨在提升浏览器内执行效率的类似“汇编”方式的实现快速运算的解决方案就可以了。

脚本里使用它其一目的是解决javascript内浮点运算等在弱类语言难以高效率执行的问题。其二两个框架将已有的成型miner所用算法实例c语言脚本直接转换成js模拟的脚本大大缩短了开发周期。可谓两全其美。

可供转换使用的工具有 EmscriptenbinaryenWABT 等。

两个框架的介绍就不详细谢了具体DOC和介绍按需去他们官网搜吧 :)

简评一下两者区别

asm.js 框架 可以由手写方式字符串书写拥有极大的可读性用于计算类的实现性能也达到同样C脚本2/3效率。

WebAssembly 框架 而是以由c语言脚本书写再通过编译成中间件file.wasm的Buffer形式实现因此执行更加高效。

PoolSocket & WebSocket 流程差异分析

要我去翻看Miner的源码我是懒得一段段跟进去看了……所以我们直接抓包看看client与server到底在说些什么吧。

PoolSocket:

client >>

{
    "method": "login",
    "params": {
        "login": "********** [ Wallet Addr ] **********",
        "pass": "",
        "agent": "xmr-stak-cpu/1.3.0-1.5.0"
    },
    "id": 1
}

server <<

{
    "id": 1,
    "jsonrpc": "2.0",
    "error": null,
    "result": {
        "id": "811233385116793",
        "job": {
            "blob": "0606e498c5ce057326423f235dcd67dec07d9cb79e3506da8b35198e7debb40be3cbc2326c1999000000008bad7c9d5b78e9c9693903e817d20c09befe2c72ee6d20f297c0026d9a6e492406",
            "job_id": "664084446453489",
            "target": "711b0d00"
        },
        "status": "OK"
    }
}

client >>

{
    "method": "submit",
    "params": {
        "id": "811233385116793",
        "job_id": "664084446453489",
        "nonce": "11018000",
        "result": "0e9b264a2a225cbbdc520b1fbef207a12e092c23325b7667c27bd0d95a590c00"
    },
    "id": 1
}

server <<

{
    "id": 1,
    "jsonrpc": "2.0",
    "error": null,
    "result": {
        "status": "OK"
    }
}

server <<

{
    "jsonrpc": "2.0",
    "method": "job",
    "params": {
        "blob": "0606e498c5ce057326423f235dcd67dec07d9cb79e3506da8b35198e7debb40be3cbc2326c199900000000253addee86a405a4553dee713dabb28bd5cbb5a6556ddb332ad46ffdcf0c073a06",
        "job_id": "183626817283220",
        "target": "58dd0700"
    }
}

.
.
.

WebSocket:

web >>

    {
        "type": "auth",
        "params": {
            "site_key": "******* [ siteKey ] *******",
            "type": "anonymous",
            "user": null,
            "goal": 0
        }
    }

srv <<

    {
        "type": "authed",
        "params": {
            "token": "",
            "hashes": 0
        }
    }

{
    "type": "job",
    "params": {
        "job_id": "931350207026116",
        "blob": "0606ffbddece05a1e21456e45a3ca88d8e0ff2f299568aecc5db053f08e04774cdfba60d0ae4db000000003d710b3b5444505391ba01b634f94d72915bda5a7999499f40f62e3046b254b403",
        "target": "ffffff00"
    }
}

web >>

    {
        "type": "submit",
        "params": {
            "job_id": "931350207026116",
            "nonce": "197aae72",
            "result": "6d9a8c2da95bcd498a4056631f1a03b51f2d6806b1c6d44e4f45fd9878b6eb00"
        }
    }

srv <<

    {
        "type": "hash_accepted",
        "params": {
            "hashes": 256
        }
    }

web >>

    {
        "type": "submit",
        "params": {
            "job_id": "931350207026116",
            "nonce": "edd815a0",
            "result": "ca182b3086f441510397d67b2323014d201aa14b89b6c1fcf59759794540a900"
        }
    }

srv <<

    {
        "type": "hash_accepted",
        "params": {
            "hashes": 512
        }
    }

web >>

    {
        "type": "submit",
        "params": {
            "job_id": "931350207026116",
            "nonce": "6e791848",
            "result": "9fec44bc7d338b5e114e138ee902066ba8d6a2a0e4c0b6090fa94571eca54900"
        }
    }

srv <<

    {
        "type": "hash_accepted",
        "params": {
            "hashes": 768
        }
    }
.
.
.

通过 Socket_dump 内容不难看出

  1. 其实输入输出都是那几个量验证登录 Wallet(siteKey)获取jobs开始计算返回计算值由Pool确认算力价值。
  1. 所有的 method 变成了 type, params 内容基本原样传递result 根据流程有所变化。

看过 coinhive.min.js 我们目前大致知道了

  1. 脚本通过浏览器端asm实现方式以尽可能高的效率完成复杂的CPU计算实现XMR挖矿。
  1. 因为web端无法直接进行Socket通信所以需要用 WebSocket 与矿池通信。

由以上内容和对wss流量的解析看出Pool连接流量中最大的变化主要在json内容构造上而核心的领取jobs、计算hash、提交到pool、确认hash有效四个步骤实际内容与一般Miner并无根本差异只是由JsonRPC2.0变更为适应前端的长连接类型WebSocket而已。

既然浏览器里的CryptoNight算法已经实现那么改造起来就hin方便辣我们只需要自己构造Pool或者构造PoolProxy接管所有的操作就能完全从Coinhive平台跳出来直接为自己的Wallet挖矿免去Coinhive平台30%的手续费。

而用算力替代网站内的广告在控制对CPU占用情况下不对用户造成卡顿同时避免在自己网站停放广告导致用户厌烦的情况下赚取用来维护网站的“零花钱”感觉也是一个更好的发展方向。

脚本改造&Pool搭建

Coinhive手续就是高广告联盟弹框就是飘

要不是30%手续费让我心如刀割说不定我就老老实实用Coinhive现成的脚本了不会有这篇文章了吧

开个玩笑……

黑客意识哪来极客情怀何在众矢之的打倒虚拟货币资本主义构造属于自己的前段挖康服务器刻不容缓

但是都写了这么长了各位看官或许也审美疲劳了那么在下一篇文章中我们再详细来聊聊如何构造属于自己的前端挖矿PoolProxy~

Emmmm……好像那篇说Webshell的第二篇文章……也忘了写了……下回一同补档……

预习班来自学一下demo再养成阅读无注释源码的习惯吧

github: https://github.com/deepwn/deepMiner

本文作者:, 转载请注明来自FreeBuf.COM

# javascript # 挖矿 # 前端黑客 # 浏览器 # CoinMiner
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
评论 按时间排序

登录/注册后在FreeBuf发布内容哦

相关推荐
  • 0 文章数
  • 0 评论数
  • 0 关注者
登录 / 注册后在FreeBuf发布内容哦
收入专辑