Một khách hàng giả mạo đã gửi một kho lưu trữ GitHub độc hại vào hộp thư đến của tôi tuần này, và chỉ bằng việc chạy tệp script khởi động, toàn bộ hai ngày làm việc của tôi đã bị xóa sạch và mọi mật khẩu lưu trong trình duyệt đều bị lộ.
"Khách hàng" này đã đăng tuyển một vị trí kỹ sư cao cấp với mức lương cao, nhắn tin rất nhanh và gửi một repo trông rất chuyên nghiệp. Yêu cầu rất đơn giản: clone, chạy npm run dev, và gửi ảnh chụp màn hình để chứng minh bản demo hoạt động—không hợp đồng, không kiểm tra lý lịch. Ngay khi máy chủ phát triển (dev server) khởi động, một đoạn mã ẩn trong tệp cấu hình đã kết nối tới một máy chủ điều khiển (command-and-control - C2), tải xuống một payload giai đoạn hai và bắt đầu đánh cắp thông tin đăng nhập từ máy cục bộ.
Cách thức cuộc tấn công diễn ra
Payload độc hại nằm trong postcss.config.js, một tệp mà hầu hết các nhà phát triển thường lướt qua vì nó thường chỉ chứa một vài quy tắc xử lý CSS đơn giản. Trong trường hợp này, kẻ tấn công đã chèn thêm một dòng JavaScript bị làm rối (obfuscated) nằm xa về phía bên phải của một câu lệnh hợp lệ, được chèn thêm các khoảng trắng để trông như bình thường. Khi lệnh npm run dev thực thi pipeline của PostCSS, dòng mã ẩn này đã chạy mà không bị phát hiện.
Malware đã thực hiện ba bước liên tiếp một cách nhanh chóng:
- Kết nối C2 – nó mở một kết nối mạng tới máy chủ do kẻ tấn công kiểm soát và thông báo về máy chủ đã bị xâm nhập.
- Tải xuống giai đoạn hai – nó tải thêm mã chứa logic đánh cắp dữ liệu thực sự.
- Đánh cắp thông tin đăng nhập trình duyệt – trên macOS, nó truy vấn khóa Chrome Safe Storage được lưu trong keychain của hệ thống. Nếu người dùng chấp nhận yêu cầu từ keychain, kẻ tấn công sẽ thu thập mọi mật khẩu được lưu trong Chrome.
Ngoài việc đánh cắp tức thì, payload còn tự ghi chính nó vào một số công cụ phát triển phổ biến—VS Code, npm, Discord—để bất kỳ lần khởi chạy nào sau đó của các ứng dụng này cũng sẽ tái kích hoạt mã độc. Một lần khởi động lại máy đơn giản không thể xóa sạch sự lây nhiễm; lệnh npm install tiếp theo hoặc việc mở trình soạn thảo sẽ làm sống lại cửa hậu (backdoor).
Những dấu hiệu cảnh báo thường bị bỏ qua
- Yêu cầu chạy mã trước khi ký bất kỳ hợp đồng nào. Quy trình tuyển dụng chính thống thường bao gồm một thỏa thuận chính thức trước khi bất kỳ công việc độc quyền nào được chia sẻ.
- Các tệp nén giả danh "bản tóm tắt dự án" (project briefs). Các tệp lưu trữ Zip hoặc RAR có thể ẩn chứa các script thực thi hoặc các tệp nhị phân độc hại.
- Yêu cầu địa chỉ email cá nhân để "vượt qua bộ lọc của nền tảng". Thủ đoạn này nhằm chuyển cuộc hội thoại ra khỏi nền tảng được bảo vệ, nơi các hành vi lạm dụng có thể được báo cáo.
- Mô tả công việc yêu cầu ứng viên nạp tiền vào ví crypto hoặc mua các token thử nghiệm. Những yêu cầu như vậy không điển hình trong các công việc phát triển phần mềm thực tế.
Các bước thực tế để giữ an toàn
- Không bao giờ thực thi mã của người lạ mà không kiểm tra. Hãy mở kho lưu trữ ở chế độ chỉ đọc (ví dụ: thông qua chế độ xem tệp raw trên GitHub) và quét mọi script, đặc biệt là các tệp cấu hình và các mục
scriptstrongpackage.json. - Coi tất cả các tệp đính kèm như văn bản thuần túy. Nếu một tệp zip được gửi đến, hãy giải nén nó trong một môi trường sandbox và kiểm tra nội dung trước khi mở bất cứ thứ gì.
- Sử dụng trình quản lý mật khẩu chuyên dụng thay vì lưu trữ trên trình duyệt. Ngay cả khi keychain của trình duyệt bị xâm nhập, kho lưu trữ của trình quản lý mật khẩu vẫn được cách ly.
- Chạy mã không đáng tin cậy trong một máy ảo hoặc container biệt lập không có quyền truy cập mạng. Điều này ngăn chặn khả năng kết nối tới máy chủ C2 của kẻ tấn công.
- Bật xác thực hai yếu tố (2FA) trên tất cả các tài khoản. Nếu mật khẩu bị đánh cắp, yếu tố thứ hai sẽ ngăn chặn các lần đăng nhập trái phép.
- Luôn cập nhật các công cụ phát triển và bật tính năng kiểm tra tính toàn vẹn tự động nếu có. Một số trình soạn thảo hiện nay sẽ cảnh báo khi các tệp cốt lõi bị sửa đổi một cách bất thường.
Nếu bạn nghi ngờ mình đã chạy mã độc, hãy coi như hệ thống đã bị xâm nhập. Hãy sao lưu dữ liệu thiết yếu, xóa sạch ổ đĩa và cài đặt lại hệ điều hành. Một lần khởi động lại đơn giản sẽ không thể loại bỏ cơ chế duy trì sự hiện diện (persistence mechanism) bằng cách ghi đè các tệp trong các ứng dụng phổ biến.
Tóm lại: chỉ một dòng JavaScript ẩn có thể biến một bản demo thông thường thành một chiến dịch đánh cắp thông tin đăng nhập quy mô lớn. Hãy coi mọi kho lưu trữ là không đáng tin cậy cho đến khi bạn đã xác minh chúng, và hãy biến việc cách ly thành một phần mặc định trong quy trình làm việc của bạn. Cái giá của sự vội vàng trong chốc lát lớn hơn nhiều so với công sức bỏ ra để kiểm tra kỹ một tệp tin.
