
Namecoin区块链是作为传统DNS注册服务商的替代产品而创建的,受到了审查制度和强制性域名没收的保护。 在过去的几年中,Dimnie,Shifu,RTM和Gandcrab等僵尸网络运营商已开始使用它来管理C&C服务器的地址。
一方面,区块链的分散性和稳定性阻止研究人员和提供者删除此类域或控制它们。 另一方面,基于区块链的基础架构具有体系结构功能:网络中的所有更改都是公开可用的,可用于研究和跟踪攻击者的行为。
本文介绍了用于在Namecoin中映射僵尸网络并进一步跟踪它们以提取新IOC的方法。 使用所描述的方法,可以编译上述僵尸网络使用的资产清单(请参阅附录)。
抒情离题
改变互联网的发明通常不仅解决社会问题,而且解决的技术问题也不多。 正是这些技术和服务使社区能够从侧面看一些似乎不可动摇的公理,重新思考它们,从头开始重新创建,只留下一个主意,并减少了多年来积累的传统惯例和限制。 区块链和比特币,托尔,维基百科-每个人成功的背后都是一小群热情的发烧友,他们真诚地相信他们正在使社会变得更好。
las,其他人经常追随他们-脱离互联网先驱者的奇怪理想,但更加实用。 他们找到
了技术
的替代应用程序,创作者没有想到(或不想考虑)。 这种替代应用程序处于允许的边界(并且更经常地隐藏在国外),通常在没有媒体帮助的情况下,对于大多数应用程序来说,它变成了
隐含的默认值 ,甚至是
唯一的 默认值 。
技术作为一种思想的等效以及使用最多的讨论方法可能导致社会排斥技术本身。 由于将其使用定为刑事犯罪,可以将不成熟的服务减少到边缘文化的水平或完全销毁。 因此,
Napster发生在很久以前,而
BitTorrent和Tor发生在不久之前,现在比特币正在发生这种情况。
这还不是这项工作的英雄-Namecoin。 Namecoin是一个旨在存储任意键/值对的区块链,其中最著名的是去中心化,耐审查性的DNS名称注册系统Dot-Bit。
在RTM僵尸网络管理小组开始使用Dot-Bit管理其C&C服务器之后,我们对Namecoin的兴趣增加了。 在某种程度上,我们想知道-在新的C&C服务器在Dot-Bit中注册后是否可以立即检测到它们? 而且,如果众所周知的域的更新没有问题,那么一种方法的开发就会突然成为一项激动人心的研究任务,该方法可以使人们检测到新域与感兴趣的人之间的联系,这是一项令人激动的研究任务。
通常,Namecoin的研究和Dot-Bit折衷指标的收集是较早进行的。
Kevin Perlow认为
这篇文章最详尽。 他是第一个提请注意从Namecoin提取数据的基本可能性的人,并描述了几种启发式技术,这些技术使专家可以查找特征与特定组中知名C&C服务器相似的域。
本研究中提出的方法与Kevin描述的专家索引和数据透视技术有几个显着差异。 我们开发的用于确定域所有者的启发式规则是从区块链的运作原理以及其中的交易形成原理衍生而来的,除了一般性描述外,还以严格的逻辑公式表示。 连同对旁路算法的正式描述,这使您可以自动执行IOC搜索,从而大大提高了调查的有效性。 此外,开发的算法不仅可以帮助查找研究小组曾经使用的其他名称,还可以让您跟踪由同一个人控制的新域的创建。
所有工作分为三章。 第一章介绍了比特币的基础知识,其代码被用作创建Namecoin的平台。 Namecoin继承了比特币中定义的许多实体,关系及其实现。 他们的理解对于进一步讨论至关重要。
第二章直接讨论Namecoin及其主要应用程序-Dot-Bit。
第三章描述了从Namecoin提取数据的建议方法,并给出了对区块链绕过算法和用于建立域之间关系的启发式规则的正式描述。
附录包含使用上述方法为某些僵尸网络收集的IOC,以及将帮助希望继续从事此主题研究的研究人员的参考资料和存储库列表。
比特币201
本节中的大多数信息是从Sergey
Pavlov_dog Potekhin的系列文章“
简而言之的比特币”中收集的。 对于说俄语的读者来说,我们认为该资源是最全面,最深入的公开资料,但令人惊讶的是它易于阅读。 对比特币内部设备感兴趣的研究人员,我们敦促不要将自己限于本节给出的摘录,而应使自己熟悉本文的全文,可在应用程序中通过引用获得这些文章的全文。 下面提供的其余信息足以理解算法的描述以及在上一章中给出的用于查找Namecoin中地址之间关系的启发式规则。
尽管习惯上以区块和连接区块链的密码学开始有关区块链的故事,但我们将从交易开始。
交易额
如您所知,最接近比特币的类似物是一本账簿,其中记录了所有硬币交易。 但是,很奇怪的是,在比特币中,没有格式为
<, >
通用表,就像没有总会计师会编辑该表一样。
取而代之的是使用非常臭名昭著的区块链,也就是说,通常存储所有交易。 为简单起见,我们可以假定这些是以下形式的消息:
<address 1> sent <amount> BTC to <address 2>
因此,如果您遍历整个区块链,则可以计算“属于”特定地址的硬币数量。
输入和输出
比特币网络上的实际交易比上述交易要复杂一些。 这是一个结构,其主要组成部分是输入和输出。
输入是您“引用”的交易。 想象一下,一次有三笔交易发送到您的地址X:
TXN_ID: 123456, VALUE: 40 BTC TXN_ID: 645379, VALUE: 10 BTC TXN_ID: 888888, VALUE: 100 BTC
例如,如果您需要花费
45 BTC
,则可以参考事务
888888
或一次参考两个事务:
123456
和
645379
。
输出-字面意思是“输出”。 我们可以假设这些是交易将导致硬币“发送”到的“地址”。 也可以有几个出口;每个出口都有自己的数量。
在下面的图片中,
C
了一个新的事务
C
,它引用两个输出
A
和
B
结果,交易在输入处具有
0.008 BTC
,然后将其分为两个输出
0.001 BTC
发送至第一个地址,
0.006 BTC
发送至第二个地址。

一次指定多个输出的能力是非常重要的功能,因为
事务输出只能一次使用,并且只能整体使用 。 如果您有一个
10 BTC
的传入交易,并且需要花掉8
10 BTC
,则只需创建一个输入和两个输出的交易:卖方
8 BTC
,卖方
2 BTC
。 如果您创建一个交易,其中输出的总和小于输入的总和(如图所示),则差额将发送到在区块中编写交易的矿工的地址。
手续费
投入总额与产出总额之间的差额称为“
transaction fee
”,即
transaction fee
。 对于矿工来说,这是第二重要的收入来源,将交易包含在区块链中所需的时间取决于它。 这是由于以下事实:每个矿工都有一定数量的未验证交易,这些交易声称属于该区块中,并且通常,该矿工只是将它们按降序排序,从而使他们的利润最大化。 因此,佣金越高,您排队的人数就越高,付款就越快。
协议的
正式规范中描述了交易的一般视图,此处给出了最常见的特殊情况之一。

previous output hash
-我们引用的交易的标识符(哈希)。
previous output index
-由于我们不需要引用事务本身,而是引用其输出之一,因此在此参数中,我们指示我们对哪个特定输出感兴趣。 编号从头开始。
1/100000000
发送到出口的中本聪(
1/100000000
BTC)数量。 它以小尾数形式记录,即
62 64 01 00 00 00 00 00
它是
0x016462
或
0.00091234 BTC
。
实际上,很少使用
block lock time
和
sequence
参数。 我们对它们不感兴趣,因此我们将省略对它们目的的描述。
但是,在标题中带有单词
script
的参数上,我们会更详细地介绍。
剧本
比特币网络具有一种基于带有公开密钥的加密算法的机制,该机制允许您创建一个系统,在该系统中,只有密钥所有者才能使用与从该密钥获得的地址相关联的硬币。 我们将弄清楚如何在后台执行此操作。
首先,在比特币内部有一种称为
Script
的简单堆栈式编程语言。 这是最简单的脚本程序:
2 3 OP_ADD 5 OP_EQUAL
每个指令称为
opcode
,总共约80条,下图显示了以上程序的执行过程。





在比特币
Script
用于设置一个条件,在该条件下可以花费输出,并能够确认满足条件。 条件(
locking script
)存储在每个出口的
scriptPubKey
字段中的事务中。 在每个输入的
scriptSig
字段中写入满足条件的确认(
unlocking script
)。
要检查使用输出的权限,您需要连接
unlocking script
+
locking script
并整体运行生成的程序。 如果执行后,
TRUE
保留在堆栈的顶部,则该事务有效。
支付给公钥哈希(P2PKH)
P2PKH
脚本用于大多数事务中,因此您应该了解它的工作方式。 这是它的一般视图:

自从比特币问世以来,该脚本就广为人知,它执行本章开头提到的任务-确保只有密钥所有者才能使用与从该密钥获得的地址相关的硬币。
这个想法是这样的:让您的朋友
B
拥有一对密钥
P
(私有)和
K
(公开)。 他使用哈希函数,从公钥获取地址
A
,然后将该地址告知您。 接下来,您向地址
A
发送例如
1 BTC
,并在
locking script
字段中输入以下内容:
只有拥有地址A
私钥A
才能进行此交易。 作为证明,首先在unlocking script
输入公钥K
,其次使用私钥P
交易签名P
当
B
决定使用您的交易作为输入时,他将创建自己的交易(例如
0.5 BTC
,并且在
unlocking script
字段
unlocking script
使用私钥
P
-
sig
和公钥K-
PubK
交易
sig
。
这是组合程序的执行过程:







区块和区块链
如果整个区块链都是一本书,那么各个块可以表示为记录交易的页面。 每个块都“引用”上一个块,依此类推,直到第一个块(
genesis block
)为止。 这就是创造区块链这种不可变性的功能的原因。 您无法采取并更改
#123
区块,以致没人注意到:区块链的设计方式是,它需要在
#124
区块,然后是
#125
区块等最顶层进行更改。
块结构如下所示:

前六个参数(
txn_count
和
txns
以外的所有参数)构成块的标题。 头哈希称为块哈希; 事务本身并不直接参与哈希。
merkle_root
负责其不变性-如果简化,则表示该块中所有事务的哈希。 您可以在此
链接上阅读有关构造Merkle树的算法的更多信息。
名词和位与块出现的过程直接相关-挖掘。
挖矿
挖矿是比特币的关键过程,包括创建新区块并同时追求两个目标。 首先是货币供应生产。 每次矿工创建一个新区块时,他都会得到N个币,然后在某个地方花费,以此奖励他,从而将新资金投入网络。
第二个也是更重要的目标是控制对网络规则的遵守。 是矿工在将脚本和交易输入包括在区块中之前对其进行检查。
那些希望更多地了解比特币财务基础的人可以为
本文提供建议。 我不会过多关注挖掘的第一个方面,而是专注于第二个方面-检查交易并在网络上启动它们。
工作证明
让你成为一名矿工。 您有10个交易要包含在该区块中。 您检查这些事务的有效性,从中形成一个块,在
nonce
字段中指定0,然后考虑块哈希。 然后将
nonce
更改为1,再次计算哈希值。
您的任务是找到一个
nonce
,以使块哈希(256位数字)小于预定数字
N
只有通过蛮力
nonce
才能搜索到这样的哈希。 因此,您想要找到随机数的速度越快,您将需要的功率就越大。
数字
N
恰好是该参数(也称为
target
),网络会根据矿工的总功率对其进行调整。 如果明天开始出现块,相对而言,每三分钟,
N
会减少,将需要更多时间搜索随机数,并且
block time
将再次增加到10分钟。 反之亦然。
这就是基于比特币和许多其他区块链的工作量证明算法的样子。 具有明显的简单性,它具有许多重要特征:
- 创建新块是一项计算困难的任务。 同时,检查块的正确性是一个简单且几乎是瞬时的操作。
- 整个网络需要10分钟才能计算出一个新块(平均)。 每个区块链的具体时间都不同,但是最重要的是平均时间是预先设置的。 而且,该时间不取决于网络参与者的数量。 即使有一天矿工数量将增加一百倍,该算法也会更改其参数,从而使查找
block time
变得更加困难, block time
又回到指定时间附近。
如上所述,挖掘过程归结为找到小于称为target
的数字的块哈希。 在块结构中,此数字写入位字段中。 例如,对于区块#277316 target
是1903a30c
。
如上所述,挖掘过程归结为找到小于称为
target
的数字的块哈希。 在块结构中,此数字写入
bits
字段中。 例如,对于区块
#277316
target
是
1903a30c
。
$ bitcoin-cli getblock 0000000000000001b6b9a13b095e96db41c4a928b97ef2d944a9b31b2cc7bdc4 { "hash" : "0000000000000001b6b9a13b095e96db41c4a928b97ef2d944a9b31b2cc7bdc4", "confirmations" : 35561, "size" : 218629, "height" : 277316, "version" : 2, "merkleroot" : "c91c008c26e50763e9f548bb8b2fc323735f73577effbc55502c51eb4cc7cf2e", "tx" : ["d5ada064c6417ca25c4308bd158c34b77e1c0eca2a73cda16c737e7424afba2f", ...], "time" : 1388185914, "nonce" : 924591752, "bits" : "1903a30c", // <-- "difficulty" : 1180923195.25802612, "chainwork" : "000000000000000000000000000000000000000000000934695e92aaf53afa1a", "previousblockhash" : "0000000000000002a7bbd25a417c0374cc55261021e8a9ca74442b01284f0569", "nextblockhash" : "000000000000000010236c269dd6ed714dd5db39d36b33959079d78dfd431ba7" }
实际上,以
bits
一次写入了两个数字:第一个字节
0x19
是指数,其余三个字节
0x03a30c
是尾数。 要从
bits
获取
target
,您需要使用以下公式:
target = mantissa * 2^(8 * (exponent - 3))
但是通常在所有在线阻止注册中心(例如,
https ://namecha.in/-Namecoin阻止注册中心)中都指定了bits。
是的,足够的理论。 我们上面讨论的应用于比特币的所有内容均同样适用于Namecoin-除了很小的差异外,我们将在下一部分中进行讨论。
名币
Namecoin是基于比特币的算法和源代码的
区块链,其主要思想是使用分布式事务注册表方案来管理域名系统,这是传统DNS的类似物。
Namecoin复制主要的比特币方法(工作量证明,10分钟的块生成间隔)和数据格式,除了少量添加之外,我们将在后面讨论。
Namecoin域的后缀为.bit。 该区域不是由IANA分配的,也没有分配给
特殊用途域的列表。 常规DNS服务器通常会响应此类NXDOMAIN请求。 但是,存在从DNS到Namecoin的网关(例如
OpenNIC ),具有Namecoin支持的公共代理,浏览器
插件以及
一个开源项目 ,该
项目可让您启动具有Namecoin支持的自己的DNS服务器。
为了管理一个名称为
facebook.bit
的域名,注册
d/facebook
密钥
d/facebook
域名的Namecoin使用
d/facebook
前缀)并确定其值就足够了。 JSON格式用于设置值。 将域解析设置为IP地址
1.2.3.4
的条目如下所示:
{"ip": ["1.2.3.4"]}
Namecoin按照
先到先得的原则分配名称。 即使对于马克·扎克伯格本人来说,从所有者那里获取
facebook.bit
域在密码上也是不可能的。
实际上,没有任何限制将Namecoin的使用限制为仅管理DNS名称捆绑-IP地址。 Namecoin可用作(并用作)分布式表,以将任意键映射到值。 但是我们将专注于其使用场景,在该场景中,它代表了区块链上的替代DNS。
域管理
Namecoin使用事务存储域记录。 即,包含程序的
scriptPubKey
字段是使用事务出口的条件,我们在上一章中花了很多时间。 为了管理记录,Namecoin引入了三个新的运算符(更准确地说,是重新定义了现有的运算符):
- NAME_NEW
- NAME_FIRSTUPDATE
- NAME_UPDATE
从名称中可以清楚看出它们的含义,但是我们将分析它们的用途和格式。
您可能会注意到缺少域删除或无效运算符。 为了清除注册表中未使用的名称,网络中内置了一种机制,该机制会自动释放36,000块(约250天)内未更新的名称。
NAME_NEW
第一步是宣布打算在网络上注册新名称。 为此,只需创建一个重量至少为
0.01 NMC
的特殊硬币(输出),其
output script
将如下所示:
OP_NAMENEW <20 byte hash> OP_2DROP <lock script>
为了演示,我将使用Stephen Morse进行的交易来
说明他的文章 。
因此,如果我们要宣布名称
d/stephenmorse
的注册,那么我们需要执行以下操作:

查看结果交易,您会发现两个有趣的事实。 首先,尽管事实上
output script
用Namecoin表示的,但从原始比特币的角度来看,它仍然有效。 Namecoin的创建者已经为他们的操作成功地选择了代码,以至于在比特币中,它们对应于基本上等同于写入常量堆栈的操作。
NAME_NEW (0x51)
代码对应于
OP_1
,后者
OP_1
堆栈1。类似的故事分别是
NAME_FIRSTUPDATE
(
0x52
或
OP_2
放入2)和
NAME_UPDATE
(
0x53
或
OP_3
放入3)。 因此,脚本的前两个步骤仅将两个值放在堆栈上。 下一个操作
OP_2DROP
将它们从堆栈中删除,以便进一步的
P2PKH
“从头开始”工作。 因此,尽管重新定义了某些操作,我们在比特币一章中介绍的所有脚本技巧也适用于Namecoin。
其次,打开特殊硬币和找零的钥匙是不同的。 尽管从技术上讲,没有什么可以阻止您重复使用相同的密钥,但是通常的做法是为每张收据生成一个新的密钥。 这样做使识别交易之间的相关性变得困难,并增加了网络中的匿名性。
乍看之下,与常识相反,似乎无法立即采用并注册一个名称以及一个IP地址似乎很奇怪。 这样做是为了让没人看到您要注册的名称(然后将其转售给您),因此没有人可以截获该名称。
例如,矿工分析网络中未确认的交易(尚未包含在任何区块中),可以创建自己的交易来注册同一域,并将其(而不是您的)包含在其区块中。 要实施此攻击,甚至不必挖掘您的块。 只需大笔费用就可以将您的交易放在网络上。 因此,
NAME_FIRSTUPDATE
两个单独的操作
NAME_NEW
和
NAME_FIRSTUPDATE
,第二个操作只能由执行第一个操作的人执行,并且只能在
NAME_NEW
进入任何块之后
NAME_NEW
。
实际上,此限制甚至更为严格:
NAME_FIRSTUPDATE
可能不早于
NAME_NEW
(大约2小时)之后的12个块。 要了解为什么此限制中的障碍不是1,不是2,不是3,而是具体为12,我们将不得不从主要故事中退后一步,弄清楚什么是
fork
和
51% attack
。
前叉想象一下,矿工正在寻找
#123456
区块。 大约在同一时间,他被两名矿工独立发现,其中一名住在澳大利亚,另一名住在美国。 他们每个人都开始在网络上分散其区块的版本,结果发现世界的一半拥有一个区块链,而另一半拥有另一个。

这可能吗? 是的,有可能。 而且,这种情况经常发生。 在这种情况下,每个节点将继续遵守其自己的区块链版本,直到有人找到下一个区块为止。 假设新块继续绿色分支,如下图所示。 在这种情况下,那些遵循红色版本的节点会自动同步绿色版本的节点,因为该规则适用于比特币(因此适用于Namecoin):区块链的最长版本为真。 红色版本的区块链将被简单地忘记,并为发现它的人提供奖励。

当然,从理论上讲,在第二步中,情况可以重演,同时使用紫色,他们会发现另一种情况,它将延续区块链的红色版本。 第三,依此类推。 但是,即使第一个分叉的可能性很小,第二个分叉的可能性更低,依此类推。 比特币历史上最长的叉子只有
四个街区 。 因此,在某个时候,分支机构之一仍然会突破,整个网络都将继续使用它。
51%攻击区块链中最长的链占主导地位的事实是基于名称为51%的攻击。
假设您是骗子,并且在商店中以
1000 BTC
购买商品。 您同意卖方的意见,并寄给他钱。 卖方检查了区块链,发现确实是这样的交易,通过了所有支票甚至进入了某个区块,例如
#123
。 在那之后,卖方转到邮件并向您发送货物。
此时,您从区块
#122
开始打开采矿场并开始采矿。 如果您有足够的能力,那么您可以超越网络的其余部分并以最快的速度计数以阻止
#124
,之后整个世界都将切换到您的区块链版本。 同时,您不会在任何区块中包含
1000 BTC
的交易,这意味着它将永远被遗忘,就好像从未被遗忘一样。 .
, . . 11
, , 6 , 0,1% , 10% . , . , Namecoin , 20% .
. , . ,
NAME_NEW
, 12 ,
NAME_FIRSTUPDATE
.
NAME_FIRSTUPDATE
该操作的目的NAME_FIRSTUPDATE
是发布在中宣布的名称NAME_NEW
,并为其指定一个值。为此,我需要在网络上启动事务,其输入是我在输出处生成的非常特殊的硬币NAME_NEW
。为了确认使用它的权利,我NAME_NEW
完全按照我们在关于章节中研究的方案,在输入脚本中提供了我的公钥和由私钥对进行的交易的签名P2PKH
。交易的结果之一将是新的特殊硬币称重,就像上一个一样0.01 NMC
。她的输出脚本应如下所示: OP_NAME_FIRSTUPDATE <Name> <Salt> <Value> OP_2DROP OP_2DROP <lock script>
Salt
是0xd5eeb22ee8117f57
我们在为脚本准备的第一阶段中创建的非常随机的数字NAME_NEW
。Name
-这是d/stephenmorse
十六进制0x642f7374657068656e6d6f727365
。该字段Value
应包含一个代表规则的解析数组,通过该规则解析名称。此处可能包含的密钥和规则的完整列表。第一近似是区域文件的类似物。上面的链接显示了Namecoin实体到熟悉的DNS实体的映射。其中最受欢迎的是ip(一个更高的示例)和ns(我们现在使用)。为了表明该域的NS服务器,我们将1.2.3.4
在Value中添加一个值{“ns”:[“1.2.3.4”]}
,但当然要使用十六进制- 0x7b226e73223a5b22312e322e332e34225d7d
。和上次一样,用关闭硬币P2PKH
。在他的示例中,斯蒂芬故意在步骤NAME_NEW上创建了重量不完全为0.01 NMC
,但具有保证金的硬币,以便在下一步中,此保证金足以支付给矿工的佣金。在一般情况下,交易将有一个额外的入口以确保佣金-还有一个额外的出口以进行交付。我们将所有信息收集到一个事务中,然后将其放入网络中。
当事务进入该块时,主机将在其表中更新密钥d/stephenmorse
on 的值{“ns”:[“1.2.3.4”]}
。现在,所有支持Namecoin的浏览器都将stephenmorse.bit
通过位于的DNS服务器将域及其子域解析为IP地址1.2.3.4
。NAME_UPDATE
我在上一节末尾提到的带有键及其含义的“表”实际上称为UTXO set (unspent transaction output)
。由于防止网络重复使用资金至关重要,因此在将交易添加到区块之前,矿工会检查是否使用了交易中先前指定的输入。为了加快此操作,所有未使用的输出都存储在单独的数据结构中。该结构在网络级别上不存在,但是由每个节点本地计算和存储。完成交易后NAME_FIRSTUPDATE
,将0.01 NMC
附有钥匙值的砝码输出到我d/stephenmorse
的桌子上UTXO
。如果此输出未用于36,000个块(超过8个月,平均每个块10分钟),那么它将被视为无效,并且相应名称为免费。在网络开始时已明确定义了36,000块的周期(以及中的特殊硬币的最小值0.01 NMC
),并且未更改。为了扩展名称的注册以及对记录的任何更改或将其转让给另一所有者,将使用交易NAME_UPDATE
。实际上,形成这种交易的规则与上述规则没有区别。交易的输入应为交易中获得的硬币的输出NAME_FIRSTUPDATE
。需要额外的输入以确保调试。在交易的两个输出中,一个是新硬币,其名称具有更新的值,第二个旨在转移佣金中的更改。硬币的输出脚本格式为: OP_NAME_UPDATE <Name> <Value> OP_2DROP OP_DROP <lock script>
与前面的情况一样,Name
这是d/stephenmorse
,并且Value
-带有值的JSON(均为十六进制)。使用P2PKH关闭出口,并将事务放入网络。
总的来说,这几乎是我想讲述的有关Namecoin中名称管理的所有内容。剩下的就是对拥有域名的成本说几句话。费用
让我们计算一下Dot-Bit
加密货币中的名称内容(基于Namecoin运行的DNS区域.bit的名称)的成本,并将数字转换为法定货币,可以与“常规” DNS域的成本进行比较。因此,从上一节可以看出,对于交易而言,NAME_NEW
域所有者的成本将是0.01 NMC
创建一个将附加区域的硬币,再加上矿工的佣金。对于交易,NAME_FIRSTUPDATE
将以旧硬币为代价创建新硬币,此外,所有者仅支付佣金。大约8个月后,所有者将必须完成交易NAME_UPDATE
以保留注册名称。这是第一年年底所需的成本。有关Namecoin的大多数文章(包括Stephen Morse先前引用的文章)基于该网络成立头几年的数据,并声称该矿工的佣金为0.005 NMC。但此后,该委员会的中值逐渐下降,并在2019年初为约0.0003 NMC。 NMC CSHA率对美元,相反,已经经历了几起几回的2015年水平达约每1 NMC 0.7 $。很容易计算出,第一年.bit区域中的域的所有者将花费0.0109 NMC或0.00763美元。也许人们会更容易记住这一数额的近似货币(50戈比)。好吧,这是与购买名称以供将来使用或抢注的方案所匹配的下限。上限呢?由于来自更新该区域的每笔交易的输入应该是来自先前区块之一的硬币,因此名称更新频率的理论最大值等于新区块出现的频率。回想一下该值的平均值是在网络启动时设置的,大约是10分钟,可以估计维护域成本的上限为15.7744 NMC或略高于$ 11。如您所见,即使在这样一种奇妙的情况下,花钱在Namecoin中使用名称,也大约等于在最受欢迎的.com区域中拥有常规域名的第一年。如果我们将比较现实的情况与平均每天进行一次更新进行比较,则.bit区域中的名称每年将花费约8美分,这比传统DNS中最优惠的报价(不低于$ 1)便宜得多。在域名的短期使用(从几个小时到一个月)的情况下,使用Namecoin的区别已经是两个数量级。考虑到服务的财务吸引力以及域名所有者的匿名性,包括缺乏对普通DNS的传统“资金追踪”,很明显,为什么Namecoin已成为服务所有者的流行网络,尤其是在僵尸网络中,断开或阻止的风险增加了。域名币中的僵尸网络
确实,僵尸网络运营商开始使用匿名Dot-Bit
来保护其C&C服务器这一事实不足为奇。另一件事更有趣-.bit僵尸网络保持活动状态多长时间。在“常规” DNS区域中注册的C&C域迟早会从所有者中撤回,这迫使运营商为注册新名称和在网络上使用新的管理服务器启动新的僵尸程序集付费。根本不可能删除.bit区域中的域,从而使僵尸网络的生存期延长了几个数量级。以pationare.bit
2016年12月注册的域名为例。它用于控制僵尸网络Chthronic
(分发基于著名的ZeuS构建的银行木马)。发行活动Chthronic
与漏洞利用程序包RIG的使用相关联,并在2016年底和2017年上半年被各种研究人员(例如恶意软件-traffic-analysis.net)进行了详细描述。可以假定该僵尸网络很久以前就已被破坏。但是,没有-僵尸网络的C&C域及其网络在启动两年多之后仍处于活动状态。从下面的屏幕截图可以看出,最近一次更新是在2018年12月进行的。
看起来很诱人,对吧?由于管理服务器的DNS名称保持不变,因此无需频繁更新漫游器代码并重新启动分发活动。保留IP地址后,仅保留更改主机的成本,但是也可以通过使用被入侵的Web服务器作为代理来降低这些成本,这些代理的外壳成本不到一美元。另一方面,任何参与者都可以公开使用区块链中的所有交易。正如我们在前几章中详细讨论的那样,Namecoin中的硬币不会消失而不会丢失,这意味着我们可以跟踪它们在地址之间的重新分配。通过了解规则和限制,并考虑到Namecoin中进行了哪些交易,我们可以找到有意义的模式,在这种模式下,交易中涉及的某些地址的统一管理将变得显而易见。在这种情况下,使用来自这些地址的硬币支付的域将具有一个共同的所有者-我们正在管理的组,该组控制僵尸网络。我们将进一步发展这个想法。国际奥委会总征收计划
让我们以RTM组的真实僵尸网络为例来描述一般搜索方案。我们将以此样本为基础,该样本被标识为Win32/Spy.RTM.N
。
从上面的屏幕截图中可以看到,启动后它将尝试获取name的IP地址stat-counter-4.bit
。我们在Namecoin中获得有关该名称交易历史的信息。
我们通过单击指向操作NAME_NEW的链接来获得创建此域的交易的标识符。显然,该交易的输入地址(由其创建域)由我们感兴趣的组进行管理。他将最初的一组数据:N3KPt8py24EAsAiKquyFgoKGyTYeR5Tmry
。
根据初始数据集,我们迭代遍历区块链,朝其增长方向(向上移动或向上移动)移动。在每个步骤的开始,我们都会获得一笔交易,在输入的某个硬币属于我们感兴趣的人。第一步,我们从初始数据集中检查交易,我们知道先验的输入硬币的所有者。检查交易是否符合启发式规则(我们将在下面公式化),该规则可确保交易结束时某个硬币(或多个硬币)与已知输入硬币属于同一个人。如果所讨论的交易满足一种或多种试探法,则这种指导性硬币将指示进一步运动的方向。花费指导性硬币的交易将是迭代的下一步。在迭代的每个步骤中,我们都会补充参与交易的域列表以及这些域所解析到的IP地址列表。这些是妥协的历史标识符(IOC),可用于法医,以及识别战术和分组方法。如果所讨论的事务不满足任何试探法,则移动停止。这意味着我们不能确定地说该交易的任何输出是由我们感兴趣的人控制的。阻止移动的另一种情况是输出地址缺少事务。我们会将这些地址保存在单独的未用硬币列表(UTXO)中。它们代表了整个研究的最大价值。由于我们确信这些地址是由我们感兴趣的人管理的,因此任何将来使用这些地址的交易都会生成一个新的,以前未知的IOC(域名或IP地址),该IOC尚未被分组使用。但是很有可能很快。要绕过区块链,将其导出到数据库很方便。为此,您可以使用例如修改后的rusty-blockparser实用程序,通过添加操作识别NAME_*
,数据结构Auxiliary Proof-of-Work
和扩展导出格式,我们在其中改进了对Namecoin的支持。下面显示了向上运动的Python伪代码。在下文中,假定区块链交易数据存储在MongoDB中。 start = "37d40bc2f3ca7415908dc9e276593b50d3120158cd540cb088246f2e2cf88b16" tx = namecoin.transactions.find_one({"id": start}) def upstream_movement(tx): global names global IPs global utxo global known_addresses heuristic_result = upstream_heuristic_test(tx) if heuristic_result and heuristic_result.guiding_outs: if tx.has_name_op(): names.add(tx.name_op.name) for ip_address in tx.name_op.get_ip(): IPs.add(ip_address) for guiding_out in heuristic_result.guiding_outs: known_addresses.add(guiding_out.address) tx = namecoin.transactions.find_one({"in.id": guiding_out.id}) if tx: upstream_movement(tx) else: utxo.add(guiding_out)
区块链绕过的第二部分是反对区块链增长的运动(向下运动或下游运动)。通常,向下移动算法与向上算法没有什么不同。移动始于原始数据集的事务。在每个步骤中,都会检查交易是否符合启发式规则(通常与向上移动的规则不同)。唯一的区别是,其成员资格被称为先验的硬币位于交易的出口处,并且启发式算法可确保同一个人在入口处拥有一个或多个硬币。如果当前交易不满足任何试探法,则向下运动也将停止。与向上运动不同,我们不能在向导之间遇到未花费的硬币,并且在向下运动中退出递归的此选项将不起作用。但是,与上升趋势一样,我们同时补充了名称列表和IP地址列表。向下移动的Python伪代码如下所示: start = "37d40bc2f3ca7415908dc9e276593b50d3120158cd540cb088246f2e2cf88b16" tx = namecoin.transactions.find_one({"id": start}) def downstream_movement(tx): global names global IPs global utxo global known_addresses heristic_result = downstream_heuristic_test(tx) if heuristic_result and heuristic_result.guiding_ins: if tx.has_name_op(): names.add(tx.name_op.name) for ip_address in tx.name_op.get_ip(): IPs.add(ip_address) for guiding_in in heuristic_result.guiding_ins: known_addresses.add(guiding_in.address) tx = namecoin.transactions.find_one({"out.id": guiding_in.id}) if tx: downstream_movement(tx)
现在考虑在沿区块链移动时将使用的启发式规则。启发式规则
共同的变化
让我们再次看一下事务,上面给出了其屏幕截图。N3KPt8py24EAsAiKquyFgoKGyTYeR5Tmry
包含用于创建新名称的资金的地址将发送到交易输入。对于交易NAME_FIRSTUPDATE
,并NAME_UPDATE
在入口处将有两个地址-一个特殊的硬币从先前事务域和额外的资金来支付佣金的区域。我将立即注意到,在交易方面,我们将讨论硬币和地址。尽管在某些作品中这些概念几乎被认为是等效的,但对我们而言,明确指出这些术语之间的区别非常重要,因为在研究过程中,我们将得出有关代币和地址的结论。说“硬币”,我们将表示交易产生的正余额。该硬币由生成该硬币的交易编号和出口索引标识。例如,上面考虑的交易输入处的硬币具有标识符5778be8e1901e9931e9b41a128a0b7f963e6e1ae72e461df2cba26e6279d433a:1
,因为它被形成为交易的输出(索引为1)5778be8e1901e9931e9b41a128a0b7f963e6e1ae72e461df2cba26e6279d433a
。像以前一样,特殊硬币将被称为面值为b的硬币0.01 NMC
,locking script
其中包含带有域名的操作。我们在“域管理”部分中详细研究了此类代币的形成机制。我们将普通硬币称为任意面额的硬币,与域操作无关的硬币。硬币的主要特性是它们的不变性。任何硬币只能使用一次,并且只能全部使用。因此,在Namecoin网络上最多提及两次:创建一次,第二次花费。说“地址”,我们是指一个标识符,该标识符唯一地标识可以打开锁定脚本的密钥对,其格式P2PKH
可以关闭位于交易输入或输出处的硬币。由于只有对应于该地址的密钥才能花费硬币,因此与地址最接近的现实世界是存放硬币(并从中花费硬币)的钱包。尽管在Namecoin中地址通常也只使用两次,但并不需要接收和消费单个硬币。重用地址的事实将对我们将来有所帮助。我们在比特币201一章中详细介绍了输入,输出和地址。因此,在交易的出口处形成了两个硬币。该地址N2hgZoWaTKoJ7FPmLuytTow3XrCCfEj2ca
绑定到的同一枚特殊硬币(称重为0.01 NMC)到达了地址。一个NKMMLwyMw4nwGuke6vd3AuDBMP18FWRaF1
零钱的普通硬币被发送到第二个地址。这是最常见的交易方案。当入口处有多个硬币时,仍然有选择,但是它们的共同特性是找零硬币总是完全相同。您可以猜测这样的事务对应于域信息的简单更新。使用属于一个人的一枚(很少是几枚)硬币进行更新付款。实际上,由于事务始终只有一位作者,因此它必须管理所有输入地址。没有这个,他将无法创建解锁脚本,这是使用该钱包中的硬币所必需的。好吧,由于此操作的所有零钱都收集在一个硬币中,因此很明显,该硬币与入口处的硬币属于同一个人。在这项工作中描述了类似的比特币计划,称为比特币one-time change
。它反映了本地比特币应用程序进行交易的方法- bitcoind
和bitcoin-qt
。一次(一次)被调用是因为这些应用程序的另一个功能。默认情况下,它们在创建的交易的输出处为硬币生成新的地址。Namecoin与比特币代码库一起,继承了这些应用程序的大部分代码,称为namecoind
和namecoin-qt
。对于普通硬币,我们可以安全地使用此启发式算法,而无需进行任何更改。地址重用以存储特殊硬币的统计数据表明,在大多数情况下,对于它们也遵守此规则。此类地址的重用非常少见。地址使用了不止一次,约占总数的6%;超过两倍-大约1%。基于Namecoin的目的,似乎合理的假设是,网络上大多数带有特殊硬币的交易都是简单的创建和更新操作,在此期间域所有者不会更改。因此,我们可以认为这种操作对应于将特殊硬币提取到新的先前未使用的地址。现在,让我们看一个带有特殊输出硬币重用地址的交易示例。为此,请进行RTM组的另一笔交易-b3c7ce9ca3a689c6236b9d6df3c257c5fab6c3985187669ccf731ac42a127a11
。特殊硬币去往
的地址NDpWDEx1mBkUYywqxDTAZZeGCfUV4GkVE8
已经在以前的交易中使用过。
如前所述,Namecoin本地客户端应用程序中的默认脚本不会导致地址重用。要将特殊硬币发送到现有地址,所有者将需要做出单独的,可选的努力,在交易形成阶段明确找出并指出退出地址。为什么可能需要这样做?唯一提到手动指定退出地址的情况,我仅在有关将域转让给另一个所有者的说明中遇到过。
如果我们考虑有关交易退出时地址的进一步命运,则可以猜想是否成立。在下图中,此事务标记为亮绿色的里程碑。可以看出,9e16f6be
stat-counter-4域上的下一个交易是使用货币地址进行的NJ8xUePv
,该货币地址与“父”交易中使用的地址没有明确的联系。显然,该域已移交给另一个人的管理。
在一般情况下,这可以是将域名出售给与所涉人员的活动无关的另一所有者,也可以是在一个人的帐户之间转移域名。第二种选择是注册新域的简单性和低成本,以及组织和商标所有者对.bit区域中的域的注册缺乏明显的兴趣。在恶意活动中发现,我们至少没有提出合理的动机来购买域名。因此,我们认为,尽管有可能将域名转让给另一个人,但具有可重用地址以提取特殊硬币的交易表示资产重组是在一组控制的多个帐户之间进行的。我们以启发式规则的形式制定上述论点,我们将其称为共同变化:, , , .
, , .
, , .
图中显示了使用此规则的方案。灰色流-普通硬币,绿色-特殊硬币。指南将是交易结束后所有硬币的对面,我们通过该硬币到达该交易:所有输出均用于向上移动,所有输入均用于向下移动。
我们注意到这种启发式方法的几个特征。首先,双向:当我们知道入口的所有者时,它既适用于向上运动,当我们知道出口处的一个硬币的所有者时,适用于向下运动。其次,特殊硬币的可选可用性:尽管在不存在特殊交易的情况下,交易与更新域无关,但上面给出的有关常规硬币所有者的逻辑推理仍然有效。用于测试事务是否符合通用更改规则的伪代码如下所示: def common_change(tx): result = {"guiding_outs": [], "guiding_ins": []} if len(tx.outs.money) != 1: return {} addr = tx.outs.money[0].address first_tx = namecoin.tx.find_one({"out.id": addr}, sort=[("block", 1)]) if first_tx.id != tx.id: return {} else: result["guiding_outs"] = tx.outs.all result["guiding_ins"] = tx.ins.all return result
共同支出
上面考虑的启发式方法除了具有双向性外,还具有另一个重要的特性。常见更改-启发式“无记忆”;验证结果仅由相关事务的特征确定,而不取决于其他启发式方法和累积数据的结果。对于遍历的第一次迭代来说,这种启发式对于数据集的初始填充是必不可少的。另一方面,很容易注意到其应用的局限性。例如,她将专注于包含两个或多个现金产出的交易。作为此类交易的示例,请考虑db4ff4082f39d0a501508706e627f26aa92712d27b4f633ded59917d201cfae5
。该交易与管理Dimnie僵尸网络的组的活动有关。
我们通过地址处理了这笔交易My7Ap3nH5f4X6Us2KiUWisd77wRpMG1MDY
在先前的CC交易记录中用作登录地址。尽管他对被研究者的态度是毋庸置疑的事实,但我们不能对其他任何出入口说相同(也可以相反)。这可能是在组地址之间重新分配硬币,在这种情况下,所有地址均由我们感兴趣的人控制。还是从任何出售Namecoin代币的交易所的地址充值。或来自与所研究人员的活动无关的其他网络成员的转移。仅凭此交易的属性不可能得出确定的结论。考虑地址N4XtLb7xpC4Zk72T8QcshKhTW17ZCyQ1j1
在此交易的输入。此地址先前已在CC交易输入时使用过(“较早”表示向下移动,意思是“未来”,“朝着区块链增长的方向”)6bffc741eb66de074c09a380fb5e6bd13d4bd5205c36a76e3682674dba08461e
,这使我们可以考虑将此地址由我们感兴趣的人来管理。而且,由于已经证明,交易输入处所有硬币的密钥都是由一个人控制的(关于输出不能说),因此我们有理由相信所有其他输入也属于我们感兴趣的组。启发式公共支出的严格条件看起来非常简单:如果已知交易输入处的至少一个地址是由某个人控制的,则此交易输入处的所有其他地址都由同一人控制。这些入口处的硬币属于同一个人。
如您所见,这种启发式仅对向下运动有意义。当朝着区块链增长的方向发展时,我们通过其中一种输入来参与正在研究的交易。在这种情况下,规则条件是自动满足的,但是没有说明事务的输出,也不允许您继续向上游移动。换句话说,这是一种单向启发式。值得注意的是,这种启发式方法的第二个特点是,在此我们首先使用了由于检查以前的交易而积累的数据-由被调查者管理的地址列表。因此,如果没有任何不依赖于累积结果(例如共同变化)的主要启发式方法,则该次要启发式方法不能用于独立运动。用于测试交易是否符合通用支出规则的伪代码如下所示: def common_spending(tx): result = { "guiding_ins": [] } for input in tx.get_ins(): if input.address in known_addresses: return {"guiding_ins": tx.ins.all} return {}
已知地址
我们将在本节的框架中考虑的最后一种启发式方法是最简单的方法。这是次要的双向启发式方法(因为它是双向的)可用于向上和向下移动。向上运动的启发式已知地址的严格公式如下所示:如果已知交易的输入(输出)上的地址是由某个人控制的,则在该地址(从该地址花费)所接收的硬币属于同一个人。
尽管启发式方法看起来像是坦率的真实性,但是此规则有助于查找硬币流中的分支和交叉点,并增加了与交易树的连接性。此外,它还可以使您不停止不属于其他启发式交易的交易。一个例子就是7a35b9cb0a16b3eba92781be014555eaa4255bd17655bb00f2b3f42c3950ac69
已经提到的Dimnie僵尸网络的交易。
在向上运动达到它之后,我们将无法借助共同的变化而前进,因为产出不止是一枚普通硬币。从交易的角度来看,我们无法说出输出中有多少硬币与输入中的硬币属于同一个人-要么全都一个,要么全无。由于地址的事实,使用已知的地址启发式方法可以使您继续前进MwMdTb8WQvoRW9jEW5dHn9SkkCJTRn31wQ
参与了CC交易cf7ac8986f9855246c6cf26df9a24aa5645cb9258bf787e034a33e75101ae1fc
,该交易创造了在上游运动中较早遇到的领域d/sectools
。为了完整起见,我们给出启发式已知地址的伪代码: def known_address(tx): result = { "guiding_outs": [], "guiding_ins": [] } for output in tx.get_outs(): if output.address in known_addresses: result["guiding_outs"].append(output) for input in tx.get_ins(): if input.address in known_addresses: result["guiding_ins"].append(input) return result
因此,现在我们有了通用的绕过算法和沿着区块链移动所必需的启发法,以便我们可以将它们放在一起以从Namecoin获得一些IOC。走吧
我们将从RTM交易开始向上和向下移动37d40bc2f3ca7415908dc9e276593b50d3120158cd540cb088246f2e2cf88b16
。在推进区块链的过程中,我们不仅会收集IOC,还会收集满足启发式的交易本身。我们使用Sankey图表可视化交易之间的币流。完整的图表太大了,无法以本文档的格式显示,因此在这里我只给出其中的一部分,这对于进一步的故事而言是必需的。
普通硬币流以灰色突出显示。其余颜色对应于特殊硬币的流动。为每个名称选择单独的颜色。白色里程碑对应于满足启发式条件的交易。右侧的红色里程碑是UTXO。我要引起注意的图表元素以蓝色里程碑突出显示。这是一个悬空的条目-一种硬币,是在算法向上移动时通过交易的输入而产生的,但是创建该硬币的交易却没有遇到他。悬空的输入表示正在研究的结构具有未连接到算法沿其移动的主干的侧分支。在所示的情况下,这是另一个独立帐户。从图中可以看出,它开始用于支付我们已经知道的域中的更改。根据这一事实,我们可以得出结论,该帐户也受调查者控制。为了使与此帐户上的操作相关联的IOC一直显示在图表上,我们将开始一个单独的向下移动,从带有悬挂条目的交易开始。类似地,在向下运动中,可能会出现悬空的出口。对于它们中的每一个,我们将从相应的交易开始进行单独的向上移动。除了控制RTM僵尸网络的组的事务之外,我们还检查了控制Shifu,Dimnie和GandCrab僵尸网络的组的事务。结果,找到了以这些组的利益注册的164个域以及与这些名称相关的277个IP地址。在撰写本文时,已收集的属于这些组的UTXO中仍有39个硬币有效。IOC列表以及组中未使用的硬币保留在其上的Namecoin地址在附录A中给出。结论
实际测试是几乎所有技术的挑战。到2000年代中期,维基百科已经成为一种如此受欢迎的受信任的信息源,通过更改文章的文字,可以控制舆论,起步并赚钱。服务历史上的这一时期以其巨大的修订战争而闻名-积极使用文章更正机制和多个交战方撤回编辑以赢得对文章内容的争议。维基百科的页面变成了国际名利场,每个人都想从字面上说出最后一句话。一方面,他们开始与修正案之战进行斗争,制定了特殊规则,以允许在发生争议的情况下暂时排除编辑该条款的可能性-直到“讨论”部分的辩论者找到折衷的措辞。另一方面,修订战争迫使Wikipedia启动动态机制来管理管理员的资源,这使他们能够迅速参与解决最热地区的冲突。此外,该百科全书利用了引起公众关注的优势,即围绕各个文章引起的冲突,以吸引更多的参与者来编辑这些文章,并实现对特定主题的最正确,最全面的报道。像Wikipedia一样,Namecoin可以成长并应对挑战吗?等一下带有折衷指标的PS表可在GitHub上获得。由 PT专家安全中心的Alexey Goncharov 发布