Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Ngày nay, một trong những kỹ thuật được sử dụng nhiều nhất để truyền bá phần mềm độc hại trên Windows Systems là sử dụng trình nhỏ giọt JavaScript (JS). Một Dropper JS đại diện, trong hầu hết các kịch bản tấn công, giai đoạn đầu tiên của nhiễm trùng phần mềm độc hại.

Nó xảy ra bởi vì các hệ thống Windows cho phép thực hiện ngôn ngữ tập lệnh khác nhau bằng cách sử dụng máy chủ Windows Script (WScript). Điều này có nghĩa là, thông qua JavaScript, nó có thể được thực hiện một cuộc gọi hệ thống đến hệ điều hành cơ bản.

Sử dụng bộ giảm giọt JS làm giai đoạn đầu tiên của nhiễm trùng phần mềm độc hại là một phương pháp cho phép các tác giả phần mềm độc hại bỏ qua NIDS, HIDS và phần mềm chống độc hại điểm cuối dễ dàng hơn so với việc bỏ một nhị phân duy nhất chứa toàn bộ logic độc hại. Đồng thời, obfuscation JavaScript dễ thực hiện hơn nhiều so với quá trình che giấu nhị phân. Hơn nữa, việc phát hiện một mô hình obfuscation khó hơn để tạo ra một chữ ký cho người nhỏ giọt độc hại do tính năng động của ngôn ngữ kịch bản.

Xem xét rằng, các kỹ thuật obfuscation tương tự cũng được sử dụng để khai thác cho các trình duyệt và để ngăn chặn hành vi trộm cắp và tái sử dụng mã. Trong bài viết này, tôi sẽ trình bày các kỹ thuật obfuscation khác nhau và một ví dụ thực tế thực tế để hiểu tầm quan trọng của việc biết cách đảo ngược một người làm giảm JS bị che khuất vì hầu hết thời gian chúng bị che giấu bởi một chuỗi một hoặc nhiều kỹ thuật.

Kỹ thuật obfuscation mã JavaScript

Mã JavaScript obfuscating sẽ làm phức tạp phân tích tĩnh của mã độc. Mục đích chính của quá trình che giấu là làm cho sự hiểu biết về logic mã khó khăn hơn trong khi để lại hành vi của mã không thay đổi.

Thông qua phân tích động, bạn có thể quan sát hành vi độc hại của mã, nhưng chỉ khi một số điều kiện là đúng. Nếu những điều kiện đó không bao giờ được đáp ứng, bạn không thể phát hiện ra hành vi độc hại của mã với phân tích động. Một điều kiện có thể là một kiểm tra nếu môi trường thực thi thực tế không được ảo hóa và nếu điều kiện này là sai, mã sẽ không thực thi. Điều này đã xảy ra với Dropper JS tôi đã phân tích. Hãy cùng nhìn vào chi tiết hơn.

Đảo ngược thủ công trở nên đáng kể khi phân tích động không thể giúp nhà phân tích.

Theo nghiên cứu đó [1], có thể xác định các kỹ thuật obfuscation JavaScript cơ bản được phân loại như sau:

  • Ngẫu nhiên obfuscation

Trong loại obfuscation này, một số yếu tố của mã JavaScript được chèn hoặc thay đổi mà không thay đổi ngữ nghĩa của mã.

Các kỹ thuật phổ biến được sử dụng trong danh mục này là ngẫu nhiên không gian trắng, ngẫu nhiên nhận xét, và biến đổi và tên ngẫu nhiên.

  • Dữ liệu obfuscation

Mục đích chính của các kỹ thuật này là chuyển đổi các giá trị biến hoặc không đổi thành kết quả tính toán của một hoặc các biến hoặc hằng số máy chủ.

    • Hai kỹ thuật chính thuộc loại này: phân tách chuỗi và thay thế từ khóa.string splitting and keyword substitution.
    • Chuỗi phân tách bao gồm việc chuyển đổi một chuỗi thành một sự kết hợp của một số chuỗi con. consists in converting a string into a concatenation of several substrings.
    • Thay thế từ khóa bao gồm đặt từ khóa JavaScript vào một biến và sau đó sử dụng biến đó thay vì từ khóa JavaScript. consists in placing a JavaScript keyword in a variable and then uses that variable instead of the JavaScript keyword.
  • Mã hóa obfuscation:

Thông thường, có ba cách để mã hóa mã gốc. Cách đầu tiên là chuyển đổi mã thành các ký tự ASCII, unicode hoặc thập lục phân đã thoát ra. Phương pháp thứ hai sử dụng các chức năng mã hóa tùy chỉnh, trong đó những kẻ tấn công thường sử dụng hàm mã hóa để tạo mã bị che mờ và đính kèm hàm giải mã để giải mã nó trong quá trình thực thi.

Ngoài ra, một số phương pháp mã hóa và giải mã tiêu chuẩn có thể được sử dụng để thực hiện obfuscation JavaScript. Ví dụ: jscript.encode là một phương thức được tạo bởi Microsoft để mã hóa mã JavaScript. Nó có thể được sử dụng để bảo vệ mã nguồn cũng như để trốn tránh phát hiện.

  • Logic obfuscation

Loại kỹ thuật obfuscation này là thao tác với luồng thực thi của mã JavaScript bằng cách thay đổi cấu trúc logic, mà không ảnh hưởng đến ngữ nghĩa ban đầu. Có hai cách để thực hiện obfuscation cấu trúc logic. Một cách là chèn một số hướng dẫn độc lập với chức năng. Một cái khác là thêm hoặc thay đổi một số nhánh có điều kiện, chẳng hạn như nếu khác, chuyển đổi trường hợp, vì, trong khi, v.v.

Sức mạnh của các kỹ thuật đó xuất hiện khi chúng được kết hợp, việc khử trùng từng kỹ thuật riêng biệt có thể dễ dàng cho một nhà phân tích. Thay vào đó, nếu chúng bị xích lại với nhau, và cũng có các tham số động trong chuỗi, chúng có thể khó phân tích.

Kịch bản trường hợp thực sự

Gần đây, tôi đã có cơ hội phân tích một máy thả JS sử dụng một số chức năng obfuscation tùy chỉnh làm xáo trộn một kỹ thuật chia tách chuỗi chung (String.fromcharcode) và tham số động cần thực hiện để thực hiện đúng lần lượt. Nó cũng có mã hóa mã hóa cho các tên biến và chức năng obfuscation tùy chỉnh chứa rất nhiều mã rác.

Đối với việc triển khai tập lệnh deobfuscator, bạn có thể chọn bất kỳ ngôn ngữ kịch bản nào có thể hỗ trợ Regex, trong trường hợp này, tôi đã sử dụng Python.

Người nhỏ giọt được gửi trong kho lưu trữ .rar, bên trong.

Băm sha256 của .rar là:

0d72340c876292dcdc8dfa5b3b1cc7b6010902a2d28b5b15c8c35a3a284e7d35

Băm sha256 của .jse là:

652566914671a9d5fb5ad0b75b6c9023fa8c9cff2c2d2254daad78ba40c14e0b

Bước 1: Giải mã tập lệnh

Mở máy thả .JSE, tôi nhanh chóng nhận ra rằng nó được mã hóa với chức năng jscript.encode do Microsoft cung cấp, theo mã ví dụ:

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Tôi đã sử dụng một nhị phân được tìm thấy trực tuyến để giải mã tập lệnh [2] ở định dạng.

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Bước 2: DEOBFUCATION Các mã hóa che khuất

Để tìm ra kỹ thuật obfuscation được sử dụng trong ống nhỏ giọt là gì, tôi cần làm đẹp mã thông qua một số người làm đẹp trực tuyến [3], bởi vì người nhỏ giọt gốc chứa nửa triệu ký tự trên một dòng, theo một đoạn mã nhỏ là kết quả :

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Lưu ý rằng tất cả các bước deobfuscation được thực hiện trên Dropper ban đầu của JS và không trên mã được làm đẹp. Mã đẹp được sử dụng chỉ để có khả năng đọc tốt hơn.

Như bạn có thể thấy, kỹ thuật obfuscation đầu tiên được sử dụng là quá trình mã hóa với ký hiệu Unicode.

Để giải mã nó ở định dạng dễ đọc hơn, tôi đã sử dụng Regex sau để phân tích các ký tự:

(u0d{3})+

Tôi đã xác định một chức năng gọi lại cho việc thay thế mỗi lần xuất hiện. Tôi đã sử dụng chức năng gọi lại để thay thế vì tôi cần thay thế động dựa trên dữ liệu được phân tích cú pháp, theo mã Python:

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Mã hóa UTF-8 của nó sẽ thay thế mọi lần xuất hiện của trận đấu.

Lưu ý rằng mã hóa không phải là obfuscation; Nó được sử dụng như một kỹ thuật obfuscation chỉ để làm cho các tên biến khó hiểu hơn.

Bước 3: DEOBFUCATION Mẫu obfuscation chính

Do đó, tôi bắt đầu nhìn xung quanh và cố gắng xác định chuỗi các kỹ thuật obfuscation cơ bản. Đó không phải là một nhiệm vụ dễ dàng vì các .JS chứa hơn 16 nghìn dòng mã. Một ví dụ sau đây về mã:

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Khi xử lý thuốc nhỏ giọt khổng lồ này, không thể xác định được từng kỹ thuật che giấu và thay thế nó bằng tay.

Vì vậy, để khử trùng nó, tôi cần phải hiểu logic mô hình obfuscation và viết một kịch bản sẽ tự động hóa chất khử trùng.

Việc chuỗi của một hoặc nhiều kỹ thuật obfuscation sẽ tạo ra một mô hình che giấu.obfuscation pattern.

Các kỹ thuật obfuscation được sử dụng trong các mẫu obfuscation là các kỹ thuật cơ bản mà tôi đã giải thích trong Chương 2.

Sau một thời gian để gỡ lỗi mã ở trên, tôi thấy rằng các chức năng được sử dụng là phiên bản bị xáo trộn của Chuỗi Return Return (FromCode (StaticParam, DynamicParam)).

Đây là một triển khai của kỹ thuật chê bai dữ liệu phân tách chuỗi.

Sau đó, tôi tập trung vào việc tìm kiếm mô hình obfuscation để tự động hóa quá trình deobfuscation thông qua kịch bản Python. Cuối cùng, tôi đã tìm thấy mô hình obfuscation sau:

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Vì vậy, chỉ để đưa ra một ví dụ, một ký tự ‘C được thể hiện bằng mã này:

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Như bạn có thể thấy, mô hình che giấu này có các lớp che giấu khác nhau.

Xác định mô hình obfuscation là một bước quan trọng trong việc đảo ngược mã bị xáo trộn JavaScript vì một khi bạn đã xác định được nó, bạn đã thực hiện 80% nhiệm vụ deobfuscation. Đó là hoạt động sử dụng nhiều thời gian nhất, nhưng nó có giá trị cho quá trình tự động hóa.

Sau đó, tôi chỉ cần thực hiện một tập lệnh để phân tích mô hình obfuscation và để thay thế các mã khi cần thiết.

Vì vậy, từ thời điểm này, nó chỉ là vấn đề tạo ra một biểu thức làm việc thường xuyên có thể phân tích mô hình che giấu mà tôi đã xác định.

Nó không phải là một nhiệm vụ khó khăn, nhưng nó chỉ cần một số thời gian và thử nghiệm. Trong trường hợp của tôi, tôi đã sử dụng một trình soạn thảo văn bản (NotePad ++ [4]) để gỡ lỗi Regex mà tôi đã tạo trước khi thực hiện nó trong tập lệnh Python.

Cuối cùng, tôi đã có Regex sau để phân tích mô hình obfuscation:

(| x27x27+) {W+:.*?, [ {.*?}.*?} [.*?] (.*? x27codex27, d {1,3})]]]]]

Quan sát mô hình obfuscation được xác định, bạn có thể thấy rằng hàm bị obfuscated data_obfuscation.String_splits (staticParam1 + DynamicParam1)) có hai tham số mà tôi cần phân tích để phân tích dữ liệu. Hai tham số sẽ là 2 số, một số sẽ tĩnh và số còn lại sẽ động. Cái đầu tiên có thể được tìm thấy gần các tham số trả về hàm, ví dụ như trong mã trên sẽ là 96 và thứ hai được truyền dưới dạng đối số trong lệnh gọi hàm và nó là 3. 96+3 = 99 là mã thập phân ASCII cho char 'c.'

Để phân tích thông số tĩnh, tôi đã sử dụng regex sau: sau đây:

returnsString.*((d{1,3})+pi);

Thay vào đó, để phân tích tham số động tôi đã sử dụng:

].*?,x27Codex27,(d{1,3}))

Để phân tích chính xác tôi đã sử dụng các chức năng của nhóm Capture trong Python và tôi đã có mã sau:

Bước 4: Điều chỉnh tập lệnh

Như mọi lập trình viên đều biết, mỗi kịch bản bằng văn bản phải được điều chỉnh để hoạt động như bạn mong đợi.

Trên thực tế, việc chạy tập lệnh trên không làm mất dữ liệu với khả năng đọc tốt nhất mà tôi muốn tiếp cận với tư cách là một nhà phân tích.

Điều này đã xảy ra bởi vì Regex chỉ phù hợp với trường hợp trung bình của phân tích cú pháp khối.

Gỡ lỗi tập lệnh, tôi nhận thấy rằng khối mã của mẫu obfuscation đã được sử dụng ở các nơi khác nhau (nghĩa là giữa các câu lệnh IF, trong các khối thử, trong khi các vòng lặp và trong các định nghĩa thay đổi). Mỗi người kết thúc với dấu ngoặc đơn hoặc dấu chấm câu khác nhau và một số trong số họ, điều đó ít phổ biến hơn và tôi không nhận thấy, đã phá vỡ trận đấu regex. Vì vậy, để điều chỉnh kịch bản của tôi, tôi chỉ cần cải thiện Regex gốc và khôi phục ký tự kết thúc của mọi trường hợp phù hợp.

Regex mới để phân tích tất cả sự xuất hiện của mô hình obfuscation đã trở thành:

(| x27x27+) {W+:.*?, [ {.*?}.*?} [.*?] (.*? x27codex27, d {1,3}) (= |

Hơn nữa, tôi cũng cần thay đổi chức năng gọi lại cho các thói quen thay thế bao gồm tất cả các trường hợp kết thúc. Sau đó, tôi đã có kịch bản sau:

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Cuối cùng, chạy tập lệnh được điều chỉnh, tôi có một phiên bản DEOBFUNCATID và có thể đọc được của Dropper chứa 241 dòng mã, theo một hình ảnh với một đoạn mã:

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Bước 5: Phân tích mẫu

Trong bước này tôi đã phân tích mã rõ ràng và dễ đọc, đó chỉ là vấn đề hiểu biết về JavaScript.

Tôi tập trung vào việc xác định các chức năng độc hại tiềm năng để trích xuất các IOC có ý nghĩa.

Trong phiên bản deobfuscated, tôi đã nhanh chóng phát hiện ra một số IOC hữu ích có thể ngăn chặn mối đe dọa này lây lan (và cũng để phát hiện mối đe dọa sau khi chạy), ví dụ như hai tệp .exe và .gop đã rơi vào đĩa trong thư mục % temp %:

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Ngoài ra, việc giữ tất cả các tên tệp được tìm thấy trên mỗi đĩa có sẵn với một tiện ích mở rộng cụ thể trong một tệp có tên là Say SaymyName.txt, trong thư mục % Temp %:

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Ngoài ra, một máy chủ C2 nơi tải trọng chính sẽ được tải xuống:

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Chúng có thể đại diện cho một bộ IOC tốt để sử dụng để ngăn chặn mối đe dọa lan truyền khắp mạng lưới nội bộ của bạn.

Tuy nhiên, tôi muốn đi sâu hơn và hiểu hai khía cạnh: thứ nhất, tại sao mẫu không chạy trong VM của tôi? Thứ hai, có phải là thuật toán phía sau máy chủ C2 để phục vụ tải trọng chính hay tôi có thể chỉ cần tải xuống .exe không?

Hướng đạo trong mã, tôi đã thấy một người đáng ngờ nếu có các điều kiện thú vị, theo mã:

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Từ đoạn mã ở trên, tôi thấy rằng người nhỏ giọt kiểm tra các tên quy trình cụ thể đang chạy và chủ sở hữu cụ thể của các quy trình.

Ở nơi đầu tiên, nó liệt kê các quy trình đang chạy và sau đó nó lưu trữ một số thông tin trong một mảng. Thông tin được tổ chức bởi mảng này sẽ là tên quy trình, đường dẫn thực thi, tên miền chủ sở hữu và tên chủ sở hữu.

Sau đó, nó sẽ kiểm tra xem trong mảng được tạo ra có chứa một số chuỗi có thể có nghĩa là môi trường thực hiện là VM, hộp cát hoặc máy kỹ thuật đảo ngược.

Đó là lý do người nhỏ giọt này không chạy trong VM của tôi.

Để trả lời nghi ngờ thứ hai của tôi, tôi đã cố gắng truy cập trang máy chủ C2 mà tôi tìm thấy, nhưng rõ ràng, .exe sẽ không được phục vụ dễ dàng.

Sau đó, tôi quyết định tìm kiếm cuộc gọi kết nối HTTP trong mã. Tôi nhận thấy rằng URL chứa một số tham số động được tạo thông qua một số thủ thuật lặp lại cho các trò chơi lặp, theo toàn bộ mã:

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

URL cuối cùng phải được định dạng như trên nếu không thì máy chủ C2Server sẽ không phục vụ tải trọng nhị phân. Biến số này có thể cần thiết là tham số thứ ba của trang PHP được tạo một cách linh hoạt bằng cách sử dụng một thủ thuật để làm phức tạp phân tích. Nếu tham số này sai, tải trọng được phục vụ đã giành được giải nén và thực thi vì nó sẽ bỏ lỡ tham số cho thói quen giải nén của tải trọng nhị phân. Một số tham số khác là tĩnh (nghĩa là param param_1) và các tham số khác là ngẫu nhiên (nghĩa là Last LastParam).

Cuối cùng, nhận xét mã cho kết nối HTTP và thêm chức năng in gỡ lỗi, tôi có thể lấy URL có thể cho phép tải xuống tải trọng nhị phân có thể chạy được:

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Chạy tập lệnh này trong CScript sẽ in URL:

Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript
Hướng dẫn reverse engineer obfuscated javascript - kỹ sư đảo ngược làm xáo trộn javascript

Điều hướng đến trang đó, tôi đã tải xuống tải trọng nhị phân chính được mã hóa trong Base64, Hash SHA256: 1572B8CC6DC1AF0403BF91E24B20F9C39F6722258329B0BAFA89

Các nhị phân được tải xuống dường như là một biến thể của ngân hàng Trojan Zusy (còn được gọi là Tinba).

Sự kết luận

Tóm lại, tôi sẽ nói rằng biết cách đối phó với Dropper JavaScript bị che giấu có thể giúp một nhà phân tích bảo mật cung cấp các IOC hiệu quả để ngăn chặn hoặc phát hiện các mối đe dọa.Nó chỉ cần một kiến thức tốt về biểu hiện thường xuyên, kiến thức tốt về ngôn ngữ kịch bản và tất nhiên cũng có kiến thức về JavaScript;Sau đó, nó chỉ là vấn đề xác định mô hình obfuscation và tự động hóa quá trình deobfuscation.

Như bạn đã nhận thấy có rất nhiều máy bay JS deobfuscator có sẵn trực tuyến.Đó là bởi vì thật khó để viết một chất khử trùng nói chung có thể khử trùng mọi thứ do tính năng động của ngôn ngữ.

Mặt khác, với tư cách là một nhà phân tích, bạn không thể chỉ dựa vào phân tích động bởi vì đôi khi nó không thể giúp được.

Một công việc trong tương lai mà tôi sẽ phát triển là một JS Deobfuscator bán tự động sẽ nhận ra mô hình deobfuscation và hướng dẫn nhà phân tích trong quá trình deobfuscation.