Trao đổi với tôi

http://www.buidao.com

7/31/09

[Virus] Phân tích obfuscated Javascript

Phân tích obfuscated Javascript

Link: http://vnhacker.blogspot.com/2006/11/phn-tch-obfuscated-javascript.html

Hôm nay một người bạn gửi cho tôi cái liên kết đến http://www.hvaonline.net, với lời nhắn là HVAOnline đã trở lại. Chà, mái nhà xưa đã trở lại, tôi háo hức truy cập vào địa chỉ trên. Bất ngờ NoScript nhảy lên dòng thông báo Scripts Currently Forbidden rồi đứng yên, không thấy hiện lên gì khác nữa. E hèm, nghi ngờ có chuyện chẳng lành đang xảy ra (có kẻ nào đó mượn danh HVAOnline phát tán virus chăng?), tôi liền xem mã nguồn của trang đó. Và một chuyến phiêu lưu thú vị bắt đầu :p.

Do Blogger không cho phép gửi nội dung có chứa các thẻ đặc biệt của HTML lên đây, nên trong các đoạn code trong bài này tôi thay thế <> bằng [ và ]. Đoạn Javascript bị NoScript chặn lại rất dài, do đó việc đầu tiên cần phải làm là chia nó ra thành từng lệnh ngắn hơn. Tôi bắt đầu tìm kiếm các dấu ;, là kí tự phân cách các câu lệnh trong Javascript, kết quả như sau (những chỗ tô đậm đã được bỏ đi để hiển thị trên blog này dễ hơn)

1. l1l=document.all;
2. var naa=true;
3. ll1=document.layers;
4. lll=window.sidebar;
5. naa=(!(l1l&&amp;amp;amp;amp;ll1)&&!(!l1l&&!ll1&&!lll));
6. OOOO=new Array();
7. OOOO[0]='very long string';
8. OOO0='fu';
9. OO00='YttZcpWlUoKfKWPd';
10. OOO0+='nction __'+'__(_'+'O0){';
11. OO0O='var%20%6C%32%3D\167i\156[remove]"
12. OOOO[0]+='very long string';
13. OOO0+='eva';
14. O000='kYekgsNOfgqSMmoZavFs';
15. OOO0+='l(unes' +'cape(_O0))}';
16. eval (OOO0);
17. O0O0='eilcFeNuqdBpfuHnmOQnNOkWj';
18. OOO0='';
19. OO0O+='%20%41rra\171%28%29[remove]';
20. O0OO='l';
21. OOOO[0]+='very long string';
22. OO0O+='%6B%3Bde\146%61\165[remove];
23. O0O0 ='very long string';
24. ____ (OO0O);
25. O0OO+='very long string';
Chà có vẻ như ai đó đang cố che dấu một âm mưu bí hiểm nào đó! Tôi liền lao vào phân tích những câu lệnh này. Các lệnh từ 1-5 không có nhiều hấp dẫn, chúng được dùng để khởi tạo một số biến có thể được sử dụng trong những đoạn mã phía sau, nơi mà bí mật đang được che dấu. Tôi có một vài nhận xét đầu tiên:
  • Tên các biến từ lệnh số 6 trở đi thoạt nhìn thì trông rất giống nhau (nhất là khi bạn xem mã nguồn các website này bằng browser) nhưng kì thực lại khác nhau. Tên mỗi biến là sự pha trộn giữa chữ O và số 0. Bằng cách chọn đại một biến bất kì và thực hiện việc tìm kiếm chuỗi đó trong text editor, bạn sẽ tìm thấy sự khác nhau của chúng đồng thời bạn sẽ liên kết được các nhóm lệnh lại với nhau. Tôi đã làm việc này cho bạn, các lệnh thực hiện trên cùng một biến được tô cùng màu, tổng cộng có tất cả 6 nhóm có ít nhất từ 2 lệnh trở lên, riêng lệnh số 9 và số 14 đứng một mình.
  • Có vẻ như có rất nhiều câu lệnh vô nghĩa, ví dụ rõ ràng nhất là câu lệnh số 9 và 14. Tôi không nhìn thấy pattern nào trong các chuỗi ở những câu lệnh này, tương tự như nhóm màu tím (20 và 25), màu nâu (17 và 23) và màu đỏ (6, 7, 12 và 21). Có hai cách để giải thích những lệnh này: a) chúng là những lệnh rác, được đưa vào chỉ để làm cho đoạn javascript thêm rối; b) các biến được gán trong những câu lệnh này sẽ được sử dụng trong những đoạn lệnh bên dưới.
  • Đối với các câu lệnh còn lại, các lệnh cùng màu có tính chất giống nhau. Các lệnh trong nhóm màu xanh dương có vẻ là các câu lệnh Javascript. Các lệnh trong nhóm màu xanh lá cũng giống các câu lệnh Javascript, nhưng là các câu lệnh đã được mã hóa bằng lệnh escape.
Hãy thử phân tích nhóm màu xanh dương, bao gồm các câu lệnh 8, 10, 13, 15, 16 và 18. Bạn có thấy gì chưa? Bốn lệnh đầu gán vào biến OOO0 một chuỗi như sau:
function ____(_O0){
eval(unescape(_O0)
}
Hàm này sẽ thực thi các câu lệnh Javascript dưới dạng chuỗi đã được mã hóa bằng lệnh escape chứa trong tham số đầu tiên của nó. Lệnh thứ 15 sử dụng hàm eval của Javascript để biến OOO0 thành một hàm của Javascript. Lệnh thứ 18 không làm gì cả.

Chà manh mối đã xuất hiện. Bạn hãy nhìn lệnh thứ 24. Đây là lệnh gọi hàm
____ đã được định nghĩa bởi nhóm lệnh màu xanh dương, và tham số của lệnh này là chuỗi tạo bởi nhóm lệnh màu danh lá. Chuỗi này, như đã phân tích ở trên, là những câu lệnh Javascript đã được mã hóa bằng escape. Bạn đã nhìn thấy những manh mối chưa?

Trước mắt cần phải giải mã những lệnh nằm trong nhóm màu xanh lá. Có rất nhiều cách để làm điều này, cách dễ nhất là sử dụng thủ thuật textarea do Tom Liston chỉ ra trong loạt bài Following the bouncing malware (rất bổ ích cho những ai đam mê món malware analysis!). Trước tiên tôi sắp xếp các nhóm lệnh màu xanh lá lại với nhau rồi áp dụng thủ thuật textarea (tôi thay document.write bằng documentwrite để hiển thị được trên blogger):
1.documentwrite("[textarea cols=100 rows=100]");
2. OO0O='var%20%6C%32%3D\167i[remove]"
3. OO0O+='%20%41rra\171%28%29[remove]';
4. OO0O+='%6B%3Bde\146%61\165[remove];
5.documentwriteln(unescape(OO0O));
6.documentwrite("[/textarea]");

Bạn sẽ thu được đoạn mã Javascript sau đây (tôi đã chỉnh sửa và tóm gọn lại cho dễ nhìn):
var l2 = window.opera?1:0;
function l3 (l4) {
[very long functions calling substr and replace many times...]
};
for[ii=0; ii[OOOO.length; ii++] {
lO+=l3[OOOO[ii]]
};
if[naa]{
documentwrite(lO)
};
Đoạn Javascript chia làm 2 phần rõ ràng:

  1. Phần đầu định nghĩa hàm l3. Nhìn sơ qua hàm này tôi thấy nó sử dụng rất nhiều các hàm sử lý chuỗi như substr, replace...do đó có thể suy luận rằng hàm này dùng để chuyển đổi chuỗi nhập vào của nó thành một chuỗi khác.
  2. Phần thứ hai sử dụng hàm l3 ở trên với tham số nhập vào chính là các chuỗi nằm trong nhóm lệnh màu đỏ rồi sau đó xuất ra cho browser bằng lệnh document->write.
Như vậy đã rõ, đoạn javascript trong nhóm lệnh màu xanh lá không có gì nguy hại, chủ yếu dùng để giải mã các chuỗi nằm trong nhóm lệnh màu đỏ rồi xuất ra cho browser. Vậy chúng xuất ra cái gì? Bạn hãy thử tìm câu trả lời xem! (gợi ý: áp dụng lại cái thủ thuật textarea ở trên). Anyway, client side "encryption" never works :p.