1 điểm bởi GN⁺ 2025-05-13 | 1 bình luận | Chia sẻ qua WhatsApp
  • Chia sẻ trải nghiệm trong quá trình phát triển defendnot, một công cụ vô hiệu hóa Windows Defender bằng cách trực tiếp tận dụng Windows Security Center(WSC) service API
  • Dự án bắt đầu từ quá trình vượt qua những giới hạn kỹ thuật và vấn đề pháp lý của dự án no-defender trước đó
  • Tiến hành reverse engineering và debugging giữa hàng loạt trở ngại như môi trường đặc biệt (MacBook arm64, debug từ xa, độ trễ cao)
  • Phân tích cơ chế vượt đăng ký Defender và cơ chế xác minh tiến trình, rồi sau nhiều lần thất bại và thử nghiệm đã cải thiện để công cụ hoạt động ổn định
  • Cuối cùng hoàn thành cả tính năng tự động chạy, đồng thời nhìn lại và thừa nhận những khó khăn của cả quá trình

Giới thiệu

  • Chia sẻ hành trình hiện thực hóa công cụ defendnot để vô hiệu hóa Windows Defender
  • Bài viết được sắp xếp chủ yếu xoay quanh những vấn đề thực tế và các pha mò mẫm/vật lộn khi làm trong môi trường thật, thay vì đi sâu vào chi tiết kỹ thuật chính
  • Tài liệu hóa chính thức và phần giải thích kỹ thuật sẽ được công bố riêng sau

Nhìn lại 1 năm trước

  • Khoảng một năm trước, tác giả đã công bố dự án no-defender, tận dụng cơ chế khiến Windows Defender bị vô hiệu hóa thông qua WSC API
  • Dự án này tham chiếu mã của bên thứ ba từ một nhà cung cấp antivirus, qua đó đánh lừa hệ thống như thể đã có một antivirus khác được đăng ký
  • Sau khi phát hành, dự án nhận được nhiều chú ý và khoảng 1.500 Star, nhưng do yêu cầu gỡ bỏ theo DMCA từ công ty antivirus liên quan nên tác giả quyết định xóa mã nguồn và kết thúc dự án

Lý do bắt đầu dự án

  • Ở thời điểm viết bài, tác giả đang ở Seoul và lưu trú tại Airbnb
  • Môi trường phát triển chính là M4Pro MacBook, và không mang theo thiết bị riêng cần thiết cho reverse engineering x86
  • Do lịch thi CTF và lịch trình du lịch, tác giả buộc phải làm việc mà không có thiết bị x86
  • Cùng với việc xem xét khả năng hiện thực hóa no-defender theo cách “chuẩn hơn”, tác giả bắt đầu khám phá xem liệu có thể triển khai độc lập, không phụ thuộc AV hay không

Khảo sát ban đầu (Ngày 1)

  • Nhờ sự giúp đỡ của một người bạn, tác giả có được wsc binary và thử tái hiện việc đăng ký WSC theo cấu trúc tương tự dự án trước
  • Đã triển khai bằng COM API của WSC nhưng gặp lỗi Access Denied
  • Tác giả xác định nguyên nhân đến từ việc WSC kiểm tra chữ ký và xác thực tiến trình gọi API
  • Khi thử inject module vào một tiến trình AV để đăng ký, AV đã được đăng ký thành công

Thay thế AV binary và các thử nghiệm bổ sung (Ngày 1)

  • Tác giả thử chạy công cụ thông qua các tiến trình hệ thống đã ký (như cmd.exe), nhưng thất bại ở bước kiểm tra PPL(Protected Process Light)
  • Sau đó tạm dừng để hẹn sẽ phân tích disassembly và trace chi tiết hơn

Thiết lập môi trường (Ngày 2)

  • Do giới hạn của MacBook arm64, việc debug Windows x86 là cực kỳ khó khăn
  • Tác giả dùng PC của một người bạn ở Mỹ từ xa (Parasec, Anydesk, v.v.) để debug và thử nghiệm trong môi trường độ trễ cao
  • Quá trình build code và debug VM đan xen phức tạp khiến tốc độ chậm lại và gây nhiều bối rối

Debug WSC service (Ngày 2)

  • Xác nhận rằng WSC service có cấu trúc DLL được svchost chạy
  • Để gỡ bảo vệ PPL, tác giả áp dụng cách vòng qua bằng driver đặc biệt rồi dùng debugger để xác nhận đã đi vào hàm
  • Tác giả phát hiện bên trong service có bước kiểm tra token WinDefend SID
  • Từ đó hình thành giả thuyết rằng có thể vượt qua quy trình xác thực bằng cách mô phỏng một tiến trình mang WinDefend SID

Mô phỏng WinDefend SID (Ngày 2)

  • Tác giả học thêm về cấu trúc token và nguyên lý hoạt động của Windows
  • Sau khi hiện thực và chạy mã mô phỏng WinDefend SID, mọi lời gọi COM đều trả về SUCCESS, nhưng trên thực tế AV vẫn không được đăng ký

Tái dựng thuật toán xác minh (Ngày 3)

  • Tác giả phân tích lại thật cẩn thận trong AV binary để xem bước kiểm tra SID có thực sự được vượt qua hay không
  • Khi kiểm tra SID không vượt qua, service còn kiểm tra thêm trạng thái nâng quyền, chữ ký binary và cờ DllCharacteristics (ForceIntegrity) của PE
  • Tác giả tái tạo hàm thực hiện cấu trúc này và thử nghiệm trên các binary lõi trong hệ thống

Tận dụng tiến trình Taskmgr (Ngày 3)

  • Tác giả thử lại với Taskmgr.exe làm tiến trình mục tiêu, nhưng WSC từ chối yêu cầu do lỗi trong quá trình truyền tên và bug IPC
  • Sau khi cải thiện cách suy luận đường dẫn file và cơ chế truyền tên AV, hệ thống hoạt động bình thường

Dọn dẹp mã (Ngày 3)

  • Tác giả sắp xếp lại chức năng và thử hiện thực tính năng tự động chạy (autorun)
  • Trong quá trình quản lý tự động chạy, có những lần thất bại ngắt quãng, buộc tác giả lặp đi lặp lại việc kiểm tra mã và môi trường để tìm nguyên nhân

Hiện thực tự động chạy (Ngày 4)

  • Tác giả xác nhận nguyên nhân là trong các tùy chọn của Task Scheduler có bật checkbox khiến tác vụ không chạy khi laptop không cắm nguồn AC
  • Sau khi bỏ thiết lập này, tính năng tự động chạy hoạt động bình thường
  • Cuối cùng, tác giả dọn dẹp mã và kiểm thử

Kết luận

  • Công việc reverse engineering trong môi trường hạn chế và bất tiện là một trải nghiệm cực kỳ mệt mỏi cả về tâm lý lẫn thể chất
  • Tài liệu chi tiết hơn về cách hiện thực WSC sẽ được công bố riêng sau

Lời cảm ơn

  • Pindos: người bạn đã cho mượn PC vào ban đêm để hỗ trợ debug và sưởi ấm căn phòng
  • MrBruh: đồng nghiệp đã tạo động lực bắt đầu đào sâu dự án và đưa ra phản hồi ý tưởng
  • Cảm ơn những người quen đã giữ liên lạc và tiếp thêm tinh thần trong suốt dự án
  • Tác giả thừa nhận tình yêu dành cho kimchi
  • Cảm ơn cả người nghệ sĩ đã để lại graffiti trên bức tường của chúng ta

1 bình luận

 
GN⁺ 2025-05-13
Ý kiến trên Hacker News
  • Cách mạnh tay nhưng xâm lấn nhất để vô hiệu hóa Defender là khởi động bằng USB Linux live, đổi tên thư mục C:\ProgramData\Microsoft\Windows Defender, rồi tạo một tệp trống ở đúng vị trí đó
    • Vì Group Policy hoạt động quá hiệu quả, nên tôi đã dựng một môi trường domain cục bộ với controller trong homelab để tự động thay đổi chính sách Defender cho mọi người dùng
    • Thật lạ là Windows lại không có manifest được ký để phát hiện kiểu can thiệp đó
    • Các sản phẩm phổ biến thực ra cũng làm gần như vậy, và đã từng làm sập khoảng 25% Internet
  • Dự án này từng gây chú ý lớn và nhận khoảng 1.5k sao, sau đó nhà phát triển phần mềm diệt virus mà tôi đang dùng gửi yêu cầu DMCA. Tôi không hiểu “phần mềm diệt virus mà tôi đang dùng” là gì, cũng không rõ tại sao người này lại gửi DMCA. Có lẽ tác giả đã reverse engineering một antivirus khác rồi đưa vào mã nguồn mở, hoặc ít nhất là có liên quan đến việc bắt chước WinDefend. Có vẻ đã có vấn đề về bản quyền
    • Theo hiểu biết của tôi, có vẻ họ đã dùng lớp vỏ của một công cụ antivirus khác để lách yêu cầu chữ ký. Điều đó có thể đủ tính biến đổi để hợp lý, nhưng đây là vùng xám (tôi không phải chuyên gia pháp lý)
    • Đúng vậy, họ đã sao chép một phần của chương trình antivirus hiện có và vi phạm luật bản quyền. Ngay đoạn phía trên phần được trích cũng giải thích rằng dự án dùng mã bên thứ ba từ antivirus hiện có để đăng ký AV với WSC
  • Nhân tiện, WSC là viết tắt của Windows Security Center
    • Cảm ơn vì đã giải thích. Thật sự rất bực khi chữ viết tắt xuất hiện lần đầu mà không được giải nghĩa
  • Cái này đúng là kỳ quặc: https://github.com/es3n1n/defendnot/… Nếu tò mò chuyện gì thực sự đang diễn ra thì xem ở đây: https://github.com/es3n1n/defendnot/…
    • Tôi muốn biết liệu ai giải thích được mớ “ma thuật” C++ này có thể nói rõ vì sao đoạn mã đó lại kỳ quặc không
    • Tôi không thấy chỗ nào lạ cả. Tôi dùng mẫu này rất ổn ở nhiều chỗ trong code. Dù ở chỗ gọi thì chữ ký có khác một chút thôi (do sở thích cá nhân). Nhân tiện, ngôn ngữ D có cú pháp tích hợp để kích hoạt khi scope kết thúc
    • Tôi không có thời gian để tự triển khai trực tiếp mẫu RAII cho mọi thành phần COM. Tôi sẽ đổi trong bản cập nhật tiếp theo
    • “Code cũng giống như cách bạn đối xử với đồng nghiệp” - Michael Feather Tóm lại, không phải AI Đoạn code này dùng để trì hoãn việc gọi hàm cho tới khi scope của một đối tượng kết thúc. Nó dùng macro C để đơn giản hóa việc định nghĩa lambda/hàm ẩn danh C phức tạp và tạo tên biến duy nhất. Tuy nhiên, macro không được viết hoa và trông giống một lời gọi hàm, nên người chưa quen có thể thấy khó hiểu. Với một số người, mẫu này đủ hữu ích để được xem là thành ngữ quen dùng. Giải thích kỹ thuật có thể xem ở liên kết trong bình luận khác
  • Năm ngoái tôi đã có một kỳ nghỉ rất vui khi reverse engineering virtual desktop của Windows, đó là một kỷ niệm tuyệt vời. Reverse engineering thật sự rất thú vị. Tôi học được nhiều điều hay, ví dụ như bên trong Windows RPC có một cơ chế nhắn tin không được tài liệu hóa: https://csandker.io/2022/05/24/Offensive-Windows-IPC-3-ALPC.html
  • Gần đây tôi đọc https://nostarch.com/windows-security-internals và điều đó khiến bài viết này càng dễ đồng cảm hơn. Tôi vốn đã biết phần nào backend hoạt động thế nào trên Windows, nhưng chương cuối của cuốn sách giải thích token và SID chi tiết đến mức tác giả đã trình bày rất kỹ
  • Tôi tò mò vì sao người ta lại muốn vô hiệu hóa WSC
    • Có thể vì hiệu năng, hoặc vì phát triển mã độc, hacking, v.v.
    • Nếu là tác nhân đe dọa thì có thể họ may mắn vì không có EDR (phát hiện và phản ứng đầu cuối) nào khác được cài. Nhưng nếu có, gần như chắc chắn họ sẽ bị chặn. Nếu là nhà cung cấp EDR, đây có thể được dùng như lời gọi API bị làm rối để vô hiệu hóa Windows Firewall. Các sản phẩm như CrowdStrike cũng có thể dùng firewall riêng hoặc thay thế Windows Firewall
    • Mọi phần mềm antivirus ít nhất đều là powervirus. Tôi không thích bị ai đó giám sát kiểu như bảo rằng không được dùng netcat.exe
    • Phần cứng là của tôi nên tôi sẽ dùng theo cách tôi muốn. Lý do chỉ đơn giản vậy thôi
    • Tôi thắc mắc vì sao người ta lại muốn tự cài rootkit vào hệ thống của chính mình
  • Điều còn tệ hơn với tôi là Check Point Harmony hoàn toàn không dùng giao diện được tạo cho Defender, mà lại hướng dẫn người dùng tự tắt Defender bằng tài liệu knowledge base
  • Nếu bạn cũng thắc mắc: WSC là viết tắt của Windows Security Center. Tôi cũng phải tra mới biết
    • Bài viết có câu “Windows Security Center-WSC là thành phần quản lý tất cả những thứ này”
  • Về đoạn “tôi đang làm việc trên arm64 macbook nên hiện không có cách tử tế nào để giả lập x86 Windows trên arm macbook”, có người hỏi UTM thì sao và nhắc rằng Parallels gần đây đã bắt đầu hỗ trợ Intel VM
    • Tôi đã thử UTM rồi, với x86 Windows thì chậm đến mức không dùng nổi. Linux dòng lệnh có thể còn chấp nhận được ở tốc độ tạm ổn, nhưng trong môi trường GUI thì bất khả thi. Windows arm64 chạy tốt, nhưng đó không phải x86 Windows nên vô dụng cho việc reverse engineering các thành phần hệ thống x86
    • Hệ thống dynamic recompilation của QEMU không hiệu quả bằng hệ thống native trên Windows hay macOS (Rosetta 2). x86 Windows trên UTM có chạy được nhưng hiệu năng rất tệ. Trên thực tế, tôi thấy chạy ứng dụng x86 trong ARM Windows VM bằng dynamic recompiler của Windows, hoặc dùng WINE với các subsystem dựa trên mã native còn tốt hơn. Nếu chỉ cần làm gì đó đơn giản và gấp thì có thể chấp nhận được. Nếu chữ “tử tế” mà OP nói bao gồm cả hiệu năng thì tôi hiểu quan điểm đó
    • Có thể tôi nhớ nhầm, cứ sửa nếu sai, nhưng có vẻ đúng là việc giả lập CPU có MMU về bản chất sẽ chậm và khó tối ưu. Rosetta của Apple và công nghệ tương ứng của Microsoft chạy nhanh vì chúng chỉ thực thi mã không gian người dùng. Chúng tránh phải giả lập toàn bộ MMU của hệ thống