- Một lập trình viên ở Canada đã bị tấn công dụ cài backdoor dưới vỏ bọc phỏng vấn VC giả, và luồng tấn công được thiết kế sát với công việc của lập trình viên đến mức bị nghi là nhắm vào người duy trì gói trên crates.io
- Kho mồi nhử trông như một ứng dụng TypeScript tên “Ticket Harbor”, nhưng dùng
patch-packagevàtypescript+5.9.2.patchđể giấu mã độc trong đường dẫn thực thi TypeScript - Stub được chèn vào giải mã base64 và XOR rồi chạy bằng
new Function(...); sau đó qua chunk ẩn trongoperators/3.pngvà stub WASM để khởi chạy payload giai đoạn 2 dung lượng 1,68MB trong một tiến trình Node riêng - Payload cuối “PinpinRAT” tạo cặp khóa RSA-2048 và khóa phiên AES-256-CBC, hỗ trợ thu thập dấu vân tay host, tải lên/tải xuống tệp, thực thi tiến trình, thao tác hệ thống tệp, truy vấn DNS và tự gỡ bỏ
- Nếu đã chạy kho này, cần lập tức ngắt mạng và đổi thông tin xác thực từ thiết bị khác, đồng thời ứng phó với giả định rằng cookie và cả bí mật được bảo vệ bằng mật khẩu có thể đã bị đánh cắp
Cuộc tấn công nhắm vào lập trình viên bắt đầu từ cuộc phỏng vấn giả
- Kẻ tấn công tiếp cận bằng một nhân vật giả tự xưng thuộc “Lua Ventures”
- Lua Ventures được giới thiệu là một VC trong lĩnh vực DeFi có trụ sở tại Singapore, nhưng trên thực tế đã ngừng hoạt động
- Tên nhân vật không được công bố vì có thể gây nhầm lẫn với những người thật trùng tên
- Email trông có vẻ thuyết phục và cũng chứa liên kết tới một hồ sơ LinkedIn bình thường nhưng có vẻ hợp lệ
- Chúng nhắc đến Lyrasing và Roadpay như các công ty đầu tư đang tìm cố vấn
- Hai công ty này có hiện diện web cơ bản, nên trông giống công ty giai đoạn đầu hơn là đồ giả
- Vẫn còn snapshot trên archive.org của trang Roadpay
- Sau vài lượt email, hai bên tiếp tục bằng một cuộc gọi Google Meet
- Người trong cuộc gọi là một nam giới có giọng Đức và nói rằng đang di chuyển
- Bản thân cuộc gọi không có điểm gì rõ ràng bất thường
Kích hoạt thực thi ngụy trang thành “bài kiểm tra”
- Sau cuộc gọi, kẻ tấn công đề xuất một “bài kiểm tra” và gửi kho mã
- Kho này được dựng như một ứng dụng bán vé phà tên “Ticket Harbor”
- Tệp
task.txtđi kèm chứa danh sách nhiệm vụ nhàm chán nhưng hợp lý, và cuối cùng có hướng dẫn thực thi- Nội dung yêu cầu chạy typecheck của kho, test suite và các lệnh build desktop/server liên quan
- Chính hướng dẫn này là trigger lây nhiễm thực sự
- Payload có thể được thực thi ngay khi TypeScript chạy, như
npm run typecheck,build,dev, hoặc khi importtypescript.js
- Payload có thể được thực thi ngay khi TypeScript chạy, như
Chuỗi thực thi ẩn trong bản vá TypeScript
- Tín hiệu cảnh báo đầu tiên là kho này trông giống một bài tập TypeScript
- Yêu cầu giống bài tuyển dụng TypeScript hơn là phân tích kiến trúc
- Khi đưa kho vào Claude để kiểm tra nhanh, các dấu hiệu bất thường liên quan đến
patch-packagelộ ra
- Thư mục
patches/nhiều bất thường- Một số bản vá trông có vẻ bình thường, đóng vai trò nhiễu để che giấu payload thật
- Ví dụ gồm
sumchecker+3.0.1.patch,@electron+get+2.0.3.patch,extract-zip+2.0.1.patch
- Mã độc cốt lõi nằm trong
typescript+5.9.2.patch- Chèn một stub chạy ngay vào đầu
typescript.jsvà_tsc.js - Stub giải mã chuỗi base64, giải mã XOR từng byte với khóa
73, rồi chạy bằngnew Function(...) require,Buffer,WebAssembly,process,__dirnameđược truyền vào hàm thực thi
- Chèn một stub chạy ngay vào đầu
- Chuỗi thực thi đi qua nhiều giai đoạn
- Bốn hook
postinstallchạypatch-package - Một trong số đó áp dụng
git update-index --skip-worktreecho tệp patch để ẩn khỏigit status - Loader đọc chunk ẩn gắn phía sau tệp
operators/3.png - Chạy một stub WASM nhỏ trong chunk
wAsmtùy biến - Thực thi payload giai đoạn 2 đã bị làm rối dung lượng 1,68MB dưới dạng một tiến trình Node riêng chạy lặng lẽ
- Bốn hook
- Mã tấn công được thiết kế để giảm dấu vết sau khi chạy
- Ẩn bản vá bằng
git skip-worktree - Dropper xóa các dòng nó đã chèn khỏi tệp patch sau lần chạy đầu tiên
- Thư mục tạm của giai đoạn 2 tự xóa khi thực thi
- Ẩn bản vá bằng
Chức năng của PinpinRAT
- Payload cuối được gọi là “PinpinRAT”
- Tên này được đặt vì các chuỗi nội bộ, và không loại trừ khả năng nó được biết đến bằng tên khác
- Không tìm thấy tham chiếu nào khác trên mạng
- Payload nằm trong nhiều lớp làm rối
- obfuscator.io
- Hai lớp base64 bổ sung
- Khi khởi động, RAT thu thập dấu vân tay host và rò rỉ ra ngoài
- Địa chỉ IP mặc định và toàn bộ danh sách IP
- Tên người dùng từ
os.userInfo().username - Hostname
- OS type, release, platform, architecture
- PID tiến trình và toàn bộ
process.argv - Phiên bản Node
- Nó cũng có cấu trúc mã hóa
- Tạo cặp khóa RSA-2048 cục bộ
- Tạo khóa phiên AES-256 ngẫu nhiên
aes_psk - Lưu lượng sau đó được mã hóa bằng AES-256-CBC và gắn thẻ toàn vẹn HMAC-SHA256
- Các lệnh được hỗ trợ cung cấp khả năng ở mức trojan truy cập từ xa
env: chuyểnprocess.envthành chuỗi JSON rồi gửi điupload: đọc và rò rỉ đường dẫn tệp tùy ýdownload: ghi byte do kẻ tấn công cung cấp vào đường dẫn có thể ghispawn: thực thi tiến trình tùy ý, kèm mở rộng shell tùy chọnls,cd,pwd,cp,mv: thao tác hệ thống tệp thông thườngdns: phân giải tên tùy ý qua resolver được chỉ địnhdismantle: tự gỡ bỏ
Chỉ dấu xâm nhập và ứng phó ngay lập tức
- Ảnh chứa payload không bị bất kỳ engine AV nào phát hiện trên VirusTotal
- Nếu đã chạy, cần lập tức cô lập hệ thống khỏi mạng
- Thông tin xác thực phải được thay đổi từ thiết bị khác
- Cần xem cả cookie và bí mật được bảo vệ bằng mật khẩu là đã bị xâm phạm
- Chỉ dấu xâm nhập liên quan đến PinpinRAT như sau
- C2:
89.124.107.161:80 - Tác vụ theo lịch trên Windows:
PinpinWrappedJs - Ngụy trang tiến trình trên macOS:
com.apple.WebKit.Networking - Biến môi trường:
NODT_PAYLOAD_PATH,NODT_PAYLOAD_ARGS - Guard chunk PNG:
WASMPACK(wAsm) PINPIN_NO_AUTOSTART=1: ngừng persistence- Cronjob chứa
mutex.js: chỉ có thể tồn tại khi có quyền RAT, và có thể không có trên macOS - Chuỗi anchor trong
typescript.js:12ff4b51,ticket-harbor-tsc-shim-anchor typescript+5.9.2.patchchứa payload- Thư mục artifact:
- macOS:
~/Library/Caches/runtime-cache/.cache-<randomhex>/ - Linux:
/tmp/.cache-<randomhex>/ - Windows:
%TEMP%\.cache-<randomhex>\ - Bên trong có
payload.jsvàmutex.js
- macOS:
- C2:
Những tín hiệu cảnh báo chỉ thấy rõ về sau
- Nhìn kỹ, trong các tin nhắn có những cách diễn đạt trông như dấu vết LLM
- Hồ sơ LinkedIn thoạt nhìn có vẻ bình thường, nhưng danh sách bằng cấp/chứng chỉ khá gượng gạo và cũng không có hoạt động thực tế
- Các liên kết mạng xã hội trên website có lịch sử thật, nhưng tên đã được đổi vào tháng 11/2025
- Bài đăng thiếu tính cụ thể và gần giống những lời khen mơ hồ về các công ty
- Website của các công ty trông hào nhoáng nhưng gần như không có hiện diện thực tế
- Kẻ tấn công không gửi lời mời lịch chính thức mà chỉ gửi thời gian và Google Meet
- Trong cuộc gọi, camera luôn tắt và người đó nói rằng đang di chuyển
- Các yếu tố cùng xuất hiện: VC có trụ sở tại Singapore, hoạt động theo múi giờ CEST, tiếp cận lập trình viên Canada, tên miền
.ccnhắm tới khách hàng Mỹ- Điều này khiến việc xác minh độ tin cậy của các tổ chức ở xa trở nên khó hơn
- Từng tín hiệu riêng lẻ không đủ rõ ràng, nhưng khi nhiều đèn vàng tích tụ cùng nhau thì đó là một mẫu hình có thể xem là đèn đỏ
Bên đứng sau và phạm vi tấn công
- Không thể xác định chắc chắn bên đứng sau
- Cuộc tấn công nhắm vào lập trình viên và bao gồm nhân vật giả, câu chuyện che đậy thuyết phục, nhiều website giả, lịch trình kiên nhẫn và bẫy
gittinh vi - Nó tương đồng với luồng “lừa phỏng vấn giả” được nhiều tác nhân sử dụng trong năm 2026
- Cộng đồng Rust trên Reddit cũng nhắc đến một trường hợp bị nhắm mục tiêu tương tự
- Cách làm này bám sát workflow của lập trình viên đến mức nếu được dựng dưới dạng script
build.rscài bẫy trong kho Rust thì rất có thể đã lừa được nạn nhân
1 bình luận
Ý kiến trên Lobste.rs
Việc tiêu đề suy đoán rằng đây có thể là kẻ tấn công được nhà nước hậu thuẫn khiến tôi thấy khó hiểu. Ở đây không có phần nào có vẻ nhất thiết cần mức độ chuẩn bị hay độ phức tạp như vậy
Có thể tưởng tượng khả năng đó, nhưng nó chỉ có vẻ hợp lý ở mức tương tự các kịch bản khác
Dù vậy, gần như chắc chắn tôi nghĩ đây không phải là kẻ tấn công được nhà nước hậu thuẫn. Loại tấn công này giờ không còn khó đến vậy
Việc cuộc tấn công này giống với ví dụ giả định tôi mô tả trong bài blog một tuần trước thật sự chỉ là trùng hợp: the hypothetical I describe in my blog post from a week ago
Tôi chỉ chọn một trong vài kiểu tấn công có vẻ hợp lý làm ví dụ cho thấy ngay cả chuyên gia am hiểu công nghệ cũng có thể bị lừa. Tôi đã thấy nhiều vụ lừa đảo tinh vi nhắm vào con người gia tăng, nhưng không biết rằng đang có một xu hướng lừa đảo phỏng vấn. Vì vậy khi biết về cuộc tấn công này, tôi thấy hơi rợn người
Tuần trước tôi nhận được một đề nghị phỏng vấn y hệt từ D____ S_____ của Lua Ventures. Tôi đã phớt lờ như hầu hết thư rác từ nhà tuyển dụng, và làm vậy là đúng
Hình như vài ngày hoặc vài tuần trước đã có một bài gửi kiểu này
Tôi có cảm giác đã có nhiều bài tương tự
Việc nói “trông giống email thật” làm tôi ngạc nhiên. Câu chữ rõ ràng là do LLM tạo ra đến mức tôi nghĩ mình đã nghi ngờ ngay từ câu thứ hai