+13

Cách Hacker chiếm đoạt $10.000 trong ví Metamask trên máy tính cá nhân

The D-Day

Ngày cuộc tấn công xảy ra, mình nhớ như in đó là vào tầm 1h30 trưa, hôm đó mình đang WFH (Work from home), lúc BA gửi tài liệu features cho mình thì Word của mình bị báo lỗi đòi license, và vì mình hay sử dụng Microsoft Toolkit / KMSPisco nên việc đó cũng không làm mình ngạc nhiên. Bật cửa sổ Chrome lên, mình type "KMS Pisco" sau đó click vào link đầu tiên, tải về, rồi code tiếp. (sai lầm số 1) Tải xong, mình giải nén file ra click vào luôn, Windows Defender báo lỗi, mình chủ quan không đọc kỹ lỗi, chỉ nghĩ "Chắc do Windows Defender nó chặn tool crack" nên mình tắt Windows Defender (sai lầm số 2) và giải nén lại, click lại. Lần này, ko báo lỗi nữa nhưng tự nhiên chả có gì xảy ra, mình cứ tưởng app bị ngu, nên cũng để đó chờ, trong lúc đó mình tiếp tục code task...

Ting, điện thoại báo lên có notification, liếc qua thấy "Trust Wallet", mình nghĩ "Chắc giá biến động, holder ko cần quan tâm" nên ko để ý

Ting, tiếp tục, lại "Trust Wallet", mình chụp lấy đt mở lên thì thấy là tin nhắn giao dịch chuyển coin ra ngoài, sững sờ....

Trong đầu nghĩ ngay đến việc 1 contract nào đó đang lấy tiền của mình, nhưng lập tức trấn tĩnh "Mình đâu có delegate cho contract nào ở ví này!"

Mở ví ra, tất cả số BNB mình để ở ví đã bị chuyển sang 1 địa chỉ lạ, tất cả số Cake đang Staking trên Pool bị unstake và đổi sang BNB chuyển luôn, tổng thiệt hại tại thời điểm đó là hơn 5k tiền tươi, tính giá BNB hôm nay tầm 600$ thì chừng đó là hơn 10k bây giờ

Cả người mình lạnh toát, điều tiếp theo mình có thể làm là shutdown máy ngay lập tức, sau đó kiểm tra lại Trust Wallet thì trong cái rủi có cái may

Cái rủi là số coin stake trên Pancake Swap và BNB trong ví bị ăn cắp, nhưng số BNB đang stake trên pool của Trust Wallet vẫn còn vì nó khóa lại, sau khi bấm unstake thì 7 ngày sau mới available coin nên hacker ko lấy được... đó là cái may

Vậy thì, mình ngồi suy nghĩ, nếu bây giờ mình unstake thì 7 ngày sau coin mới về, lúc đó chắc hacker nó quên mất mình rồi cũng nên...

Nhưng tiêu cực hơn 1 tí, lỡ nó scan address ra số coin đang stake này, nó bấm unstake và chạy tool cứ vài s quét address 1 lần, có coin là chuyển đi liền thì oan mạng 😦

Cốt lõi ở đây, hacker muốn chuyển coin của mình tất phải nắm được ví, làm được điều đó chắc chắn hacker đã có đc quyền access vào wallet của mình, wallet mình cài ở 2 thiết bị: iPhone đang xài và PC vừa tải cái phần mềm kia => PC là khả năng cao.

Nhưng lúc mình khởi động app, kể cả hacker có quyền vào máy mình cũng không thể nào vào đc Wallet bởi vì MetaMask có mật khẩu, vậy làm sao?

Những sai lầm cá nhân

Tình huống ở trên là thật, nó xảy ra với bản thân mình, và sai lầm của mình đã phải trả giá bằng tiền ảo (mua bằng tiền thật 😃) Trong sự việc trên, sai lầm của mình là:

  • Không kiểm tra kỹ phần mềm đã tải về, tại vì lúc unrar ra mình đã thấy file size 600mb hơn, thầm nghĩ "KMS dạo này nặng nhỉ?" nhưng ko để ý => Cẩu thả
  • Mật khẩu sử dụng cho MetaMask lại đặt là mật khẩu hay dùng giữa các tài khoản => Hạn chế và triệt để ko để việc này xảy ra, nếu ko bạn sẽ mất liên hoàn mất
  • Sử dụng phần mềm crack => Thật sự nếu trên máy có nhiều thứ quan trọng và thường xuyên làm việc trên nó thì bạn nên xem xét sử dụng phần mềm bản quyền, cũng như cài AV xịn Từ những sai lầm trên, đã dẫn đến bài học cho mình, giờ đi sâu vào phần chính nào...
  • Mật khẩu lưu trên trình duyệt => Cái này cũng rất nguy hiểm, đừng nghĩ nó an toàn, nó chỉ tiện thôi, các bạn có thể dùng Kaspersky Password thay thế.

Hình dung cách tấn công

Như đã nói sơ qua ở trên, Hacker muốn lấy coin của mình thì phải có quyền truy cập ví, mà có quyền truy cập ví thì nó làm gì cũng đc... ở case trên mình còn cơ số coin khác đang stake, đống đó mà hacker phát hiện ra thì nó chạy tool auto chuyển tiền khi address có token là chuyện dễ như giỡn chơi. Để truy cập ví thì có 2 cách

  • Truy cập qua MetaMask, nhưng MetaMask mình có đặt pass lock
  • Truy cập qua primary key, nhưng Primary key mình thậm chí ko lưu ở máy, đt mà ghi ra giấy bằng bút bi, từ rất lâu rồi và cất ở nơi chỉ 1 mình biết, chắc chắn

Như vậy, mình sẽ tiếp cận theo hướng 1, là Hacker truy cập qua MetaMask bằng Pass lock

Pass lock sử dụng cho MetaMask là 1 pass share, mình hay dùng của nhiều tài khoản cho dễ, và có lưu lại trên trình duyệt Chrome để auto fill cho 1 số trang mình hay đăng nhập. Như vậy khả dĩ nhất là kịch bản như thế này:

  • Hacker scan trên máy mình lấy được data trình duyệt, sau đó dump data về và lấy được danh sách mật khẩu, tài khoản, trang web sử dụng (nếu hên hên có thể dump cả acc bank ở đây)

  • Hacker scan trên máy mình thấy có cài MetaMask, dump luôn data của MetaMask về

  • Hacker sử dụng các mật khẩu có được ở trên và truy cập được vào MetaMask, tẩu tán tiền của mình

Okay, sơ qua như vậy thì mình khá hài lòng vì hình dung ra được khả năng như vậy, nhưng cụ thể làm như thế nào?

Thực chiến

Cách dump data Login/Pass từ Chrome

Okay, đầu tiên, làm sao lấy được data cụ thể là tài khoản, mật khẩu, trang web đã lưu trên Chrome? Chrome có nhiều profile, mỗi Profile sẽ có những data riêng lẻ, như vậy chắc chắn nó sẽ xài Database để lưu trữ, sau một hồi lần mò thì mình tìm ra file này

image.png

Nó nằm trong thư mục của Profile, đường dẫn trên ảnh, tên rất hợp ly, "Login Data" 😃)

Dùng Hex Editor (cụ thể là UltraEdit - khoe tí là xưa mình hay xài thằng này hex IP main của MU Online nên quen tay), view file và thấy chút "thông tin quan trọng"

image.png

Từ đây suy ra được file này là 1 file SQLite, cụ thể SQLite là gì mình ko bàn ở đây, anh em có thể tìm hiểu thêm nếu chưa biết

Dùng SQLite DB Browser để đọc nó, ta thấy tables như sau

image.png

Table "logins" có vẻ hay ho, ta mở nó lên xem

image.png

Chà chà, quá nhiều thông tin hay ho, vậy chắc chắn password lưu ở đây rồi, nhưng nó đã bị mã hóa

image.png

(Profile demo này mình xài mấy acc Capcut mua nên tên acc hơi ngu tí anh em thông cảm bỏ qua)

Rồi, bây giờ tìm cách crack đống pass này, sau một hồi vòng vèo thì có khá nhiều solution trên mạng, tha hồ lựa, mình pick 1 cái bằng C# và sửa 1 chút để chạy được, sau khi chạy thì crack thành công

image.png

Như anh em đã thấy, pass nó chính là dãy cuối cùng, chính xác thứ mình lưu luôn, vậy là mình đã giải quyết câu hỏi đầu tiên, nó lấy pass mình như thế nào !

Làm thế nào lấy được thông tin MetaMask

Phần còn lại của câu hỏi, làm sao lấy được MetaMask đang chứa trên máy và truy cập vào nó, lúc đầu mình nghĩ là hacker làm cách nào đó mà "dump" được cả data về sau đó import vào Chrome rồi ngồi nhập pass hoặc chạy tool brute force pass trên trình duyệt nhưng mà hình như mình nhớ ko nhầm là MetaMask có cơ chế nhập sai 5 lần pass lock là mất thông tin ví đó luôn (anti-bruteforce), nhớ là vậy hay nhớ nhầm qua "Trust Wallet" trên mobile ta 😄

Nghĩ như 1 hacker, mình lên mạng tìm cách recovery passphrase từ 1 ví MetaMask và may mắn tìm được 1 số resource, và thật "kỳ lạ" là yêu cầu của cách đó như sau

  • Bạn phải có pass lock (chính là pass mình dump ở step trước)

  • Vì lý do gì đó, bạn có pass lock nhưng không access được ví (chắc ý nó nói extension lỗi hay đại khái thế) thì làm theo nó

Có 2 cách: Cách 1 tại thời điểm bị hack, mình đã áp dụng thành công nhưng hiện tại khi viết tut này thử lại ko được nữa, và mình có update cách 2, nhưng vẫn trình bày cho anh em

Cách 1: Với phiên bản MetaMask cũ, có thể chạy lệnh "chrome.storage" trên Dev Tools

Cách này work với phiên bản 10.25.0 trở lui của MetaMask (tested)

Click phải vào MetaMask trên thanh công cụ, chọn Popup Inspect

image.png

Nhập lệnh sau vào console

chrome.storage.local.get('data', result => {
var vault = result.data.KeyringController.vault
console.log(vault)
})

image.png

Có được thông tin của nó, dùng Key Vault Decryptor để giải mã (dùng kèm pass lock)

image.png

"Mnemonic" chính là 12 ký tự recovery của ví, chúng ta có thể chọn chế độ quên mật khẩu của MetaMask để import ví mới vào, sử dụng 12 ký tự này

Cách 2: Với phiên bản MetaMask mới nhất, không thể chạy lệnh "chrome.storage" trên Dev Tools

Cách này work với phiên bản mới nhất của MetaMask (tested), ở phiên bản mới, ta không thể chạy lệnh trên do Chrome đã chặn (có 1 PR làm điều này)

image.png

Tìm hiểu 1 chút thì chính chủ MetaMask có link hướng dẫn sau: https://support.MetaMask.io/managing-my-wallet/secret-recovery-phrase-and-private-keys/how-to-recover-your-secret-recovery-phrase/ nhưng mình làm theo không được, tất cả file .ldb đều báo can not decrypt như ảnh

image.png

Nếu bước này các bạn decrypt được thì bỏ qua ko cần đọc phần dưới nha, còn ai xui xẻo như mình thì đọc tiếp

Không thể decrypt ldb, mình chỉ còn cách vọc xem ldb này nó chứa cái gì, và như tutorial kia nói thì ko phải file "ldb" nào cũng chứa data mình cần, nên chúng ta đầu tiên cần xem xét xem file ldb nào quan trọng. Thông thường theo kinh nghiệm của mình thì những file có cái date created / modified mới nhất là những file chứa data (các bạn có thể test bằng cách lock MetaMask lại rồi unlock nó, sẽ thấy file ldb nào đó đc update thì chính nó). Còn trong case như hacker thì mở hết ra cũng đc, có 3,4 file là cùng.

image.png

Dùng UltraEdit hay bất cứ 1 Hex Edit nào, open file đó ra, tìm key "salt

image.png

Cụm "salt" trở về trước là thứ cần tìm, nói chung anh em copy hết line này bỏ lên Notepad rồi xử lý sao cho nó về kiểu json cute nhất có thể

image.png

Bỏ lên Notepad nhìn rất ngu, nhưng không sao, khó khăn mới có anh hùng chứ

image.png

Chỗ mình đánh dấu anh em sửa thành "data" cho mình, vì sao? Đó là "kinh nghiệm", vì ở cách 1 ta thấy, chuỗi key vault cần thiết sẽ bắt đầu là "data"

Tiếp theo, anh em cần là "kiến thức", kiến thức để biết rằng cái đống data trên thật ra sẽ là chuỗi json hoàn chỉnh có thể đọc được (parse được bằng tool view json nào cũng đc), vậy tiếp tục đi xóa mấy cái ò é và phục hồi json nào

image.png

Những chỗ mình tô màu là xóa đi nhé

image.png

Được như trên, thì bấm Ctrl+H để Find and Replace, nhập Find là ", Replace with là ", mục đích để bỏ dấu "" trước "

image.png

Kết quả gọn gàng đẹp đẽ, cầm đoạn json đó mang lên Json Editor Online view xem được chưa

image.png

Nó báo lỗi, sửa luôn cho nóng, đây gọi là "trải nghiệm"

image.png

Okay, được đoạn Json ngon rồi, đây chính là Key Vault mà ta muốn, mang nó sang https://MetaMask.github.io/vault-decryptor/ để giải mã nhé

image.png

Vậy là đã có được cả 2 thứ cần, password dump từ Chrome và 12 ký tự, coi như có cả ví rồi hehe

Chờ chút, có gì đó không đúng ???

"Nhưng 2 cách trên đều cần pass lock, nếu không có pass lock làm sao dùng Key Vault Decryptor ?" Bạn sẽ hỏi tôi như vậy... đúng, nếu không có pass lock thì bạn không thể làm gì được cái Key Vault đó, chính sự an toàn của MetaMask đảm bảo điều đó, ngay cả bản thân họ cũng không giúp được bạn nếu bạn không có pass lock. Câu chuyện con gà và quả trứng bắt đầu từ đây:

  • Ta cần tìm pass lock để decrypt Key Vault, nếu ko có pass lock thì có tìm ra Key Vault cũng thừa, vì nhập ko đúng pass thì ko Decrypt được Đúng, vì thế nên hacker brute force cái đống password của mình ở trên để xử lý, took Key Vault Decryptor kia mã nguồn public, hoặc bạn có thể Ctrl+S lưu nó về và edit bundle.js để modify code brute force với cái list password bạn có là đc ^^ , hết list pass mà ko được thì thất bại ^^

Tuyệt chiêu cuối cùng

Ở case của mình, may mà hacker không biết mình còn coin đang stake, chứ nếu biết thì hacker có thể dọn sạch nó luôn bằng cách extract primary key của mình và chèn vào tool, cái tool đó mình search thấy bọn Ấn Độ bán đâu tầm 4,5 BNB thời điểm đó, mà thật ra cơ chế cũng nó cũng có gì đâu, mình đã thử viết lại và thời điểm đó mình thậm chí còn định run tool để chơi vs hacker luôn chứ sợ tay ko chơi ko lại....

Extract Primary key

Khi đã truy cập được ví ở cách trên, các bạn vào MetaMask chọn Account Details và chọn Show Primary Key

image.png

Primary key này sẽ dùng ở các đoạn code Smart Contract để làm việc, đại khái 1 đoạn part code như sau (Mình ko cung cấp source code con BOT này vì nó nhạy cảm, nhưng các bạn hoàn toàn có thể tự viết đc, ý tưởng là 1 con bot tự động check tài khoản và gửi tiền đi nếu tài khoản có tiền, sử dụng primary key)

 const wallet = new ethers.Wallet(privateKey);
 const walletAcc = wallet.connect(provider);
 const walletBalance = await provider.getBalance(walletAcc.address);
 ...
 const data = await account.sendTransaction({
                        to: addressReceiver,
                        value: amountToSend
                    });
                    console.log(`Hacked:  ${ethers.utils.formatEther(amountToSend)} ETH`);
          

Đấy, cho con bot này run cứ check tài khoản vài s 1 lần nếu dương tiền thì dương tiễn tài khoản đó luôn, ớn vãi 😦

Lời kết

Bài viết đến đây là kết thúc, nó là bài học được mình đúc kết ra bằng tiền mặt, bằng mồ hôi và cả nước mắt vì tiếc tiền, nên những kiến thức trong bài là tự mình đặt vào vị trí của hacker để suy nghĩ và giải quyết vấn đề, mong các bạn đọc và có thêm kiến thức chứ đừng dùng nó để đi làm điều xấu là không tốt nha ^^

Kiến thức trong bài cũng giúp ích cho anh em nào bị trường hợp ko access được ví nhưng vẫn nhớ pass, ví dụ như case: Máy tính bị lỗi ko vào được win thì dùng USB Boot vào copy data ra xử lý như trên vẫn được nha.

Chúc các bạn thành công

P/s: Cái passphrase trong bài là ví demo của mình nha, anh em đừng vô ko có đồng nào đâu 😄


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí