Oct 2, 2009

Phân Tích về Y!M Protocol [Toàn tập]

Giới thiệu chủ đề

Ta đã biết Instance Message là một nguồn thu lợi nhuận khổng lồ trong lĩnh vực Information & Communication Technology (ICT). Bên cạnh đó Yahoo Messenger là chương trình phổ biến ở Việt Nam cũng như trên toàn thế giới.

Bài viết này sẽ tìm hiểu Protocol của Y!M, nhằm phục vụ cho việc thiết kế các chương trình có khả năng tuỳ biến nội dung chat (Ví dụ: Center Tra cứu thông tin, các công cụ tinh chỉnh, ngăn quảng cáo phiền phức, hoặc dựa vào đó để viết ứng dụng trên nền mobile J2ME. …).
Các tài liệu liên quan hiện có từ nguồn Internet đều thuộc dạng “Không chính quy” (Unofficial documentation) do những nhóm người đi đầu trong việc “mổ xẻ” Yahoo biên soạn (Yahoo! chỉ chính thức phát hành các tài liệu cho việc thiết kế plugin đi kèm sản phẩm Y!M của họ). Dĩ nhiên Yahoo không hề mong chờ kiểu tài liệu unofficial này- một điều rất dễ hiểu là các ứng dụng “không chính quy” đã không hiển thị các hợp đồng quảng cáo của Yahoo!Inc, mà còn làm điều ngược lại: tự quảng cáo bằng hình tức tin nhắn quảng bá (spam – broadcast msgs).

image003

YMSG Protocol

Yahoo Messenger Protocol (YMSG) là một Protocol tầng Application chạy trên nền TCP, hoặc HTTP, SOCKS. (Tham khảo thêm các định nghĩa về TCP, HTTP, SOCKS nếu muốn tìm hiểu thêm)

Với YMSG Protocol, Yahoo có 3 kiểu kết nối chính đến server:

- Kết nối trực tiếp (Direct connection)
- Kết nối qua Http
- Kết nối qua Socks (Socks 4, Socks 5)

Chúng ta sẽ tìm hiểu kiểu kết nối trực tiếp (Direct connection) đến server csc.msg.yahoo.com [port 5050] – sẽ trình bày chi tiết ở các phần sau.

Mô hình phân tích & Công cụ:

+ Một máy client sử dụng modem ADSL, default config, nghĩa là kết nối được Internet :)

+ Yahoo Messenger version 8.x (Thời điểm mình bắt đầu thực hiện thì bản mới nhất là 9.0 chỉ đang là thử nghiệm- beta test)

+ Wireshark version 1.0.2 (Dùng để bắt gói tin)

I) GIỚI THIỆU CHUNG

1. YMSG Packet

Qua quá trình capture Y!M packets từ phía client, ta thấy được YMSG luôn có cấu trúc gói tin (Packet) như sau:
[ YMSG || Version || Packet Length || Service || Status || Session ID || Content ]

Trong đó:
YMSG:

Độ dài: 4 bytes (2 words)
Giá trị: Tên của protocol, luôn có ở đầu mọi Packets liên lạc giữa server-client (SC)

Version:

Độ dài: 4 bytes
Giá trị: Chỉ rõ version của giao thức kết nối
Ví dụ: version 15 là: 0×00, 0×0f, 0×00, 0×00 (thường thấy với bản client 8.x) Các bye 00 chỉ là các byte đệm.

Packet Length:

Độ dài: 2 bytes
Giá trị: Chỉ rõ số bytes của section Content gửi đi. Về lý thuyết giá trị tối đa là 0xffff = 65535 (2 bytes long) nhưng thực tế độ dài các gói tin chỉ nhỏ hơn 1000.

Service:

Độ dài: 2 bytes
Giá trị: Nói rõ cho SC biết dịch vụ nào cần được request/respond

Status:

Độ dài: 4 bytes
Giá trị: Chỉ rõ mã trạng thái của dịch vụ đang thực hiện (success/ failure/ ack/ etc..)

Session ID:

Độ dài: 4 bytes
Giá trị: Cho biết mã hiệu của kết nối SC đang thực hiện, giá trị do server khởi tạo, và đôi lúc có sự thay đổi trong 1 phiên làm việc (hiếm gặp), lúc đó client cũng phải thay đổi session ID theo giá trị mới này.
(Giá trị này cho thấy 1 server phục vụ được tối đa 0xff ff ff ff lượt truy cập)

Content

Độ dài: Bằng độ dài được chỉ rõ ở section Packet Length
Giá trị: Đây là một chuỗi các giá trị đi theo cặp như kiểu vertor (key/value). Key có định dạng String, Value có các kí tự thuộc kiểu ASCII, đôi lúc có giá trị là null. VD: 1 == 0×31; 21 == 0×32 0×31;
Các cặp trong trường Content này được phân cách nhau bởi cặp dấu “phẩy” theo chuẩn Yahoo {0×30 0xc080}

Ví dụ 1 đoạn Packet đã Decoded ra mã text (ASCII):

Version: 15

Packet Length: 12

Service: Authentication (87)

Status: Default (0)

Session ID: 0xb9f54600

Content: 1300200viet_vq300200

Kết luận:

+ Tổng độ dài phần header của 1 đoạn Packet luôn là 20bytes

+ Giá trị version luôn là 15 (0×0F) cho Y!M 8.x

  • ViệtQ

Phần 2

2. Quy trình giao dịch
Sơ đồ giao dịch giữa SC có dạng như hình dưới, trong đó các kết nối có kí hiệu “*” có thể tồn tại hoặc không.

ymsg_hsh

1) Bước đầu tiên, Verify:

Nhằm xác thực một kết nối đến Yahoo server, bước này cho biết hệ thống mạng đang hoạt động bình thường.
- Service: Verify (76)
- Status: Default (0)
- Content: Null

2) Authorization:

Xin quyền xác thực tài khoản
- Service: Auth (13)
- Status: Default (0)
- Content: Username

Server sẽ phải tiếp nhận và đáp ứng lại một khoá chứng thực, theo kiểu challenging response (Xem thêm slide An toàn mạng), nếu quá trình chứng thực thành công, Username sẽ được thiết lập một flag Available (Online)

3) Buddies List:

Tiếp tục quá trình đăng nhập, trao đổi danh sách bạn bè, trạng thái
- Service: List (85) / (241)
- Status: Default (0)

4) Ping

Xem xét các nick online và status của nó.

5) Thực hiện chatting và các tuỳ chọn nâng cao khác (Chatroom, đổi giao diện chat, webcam….)

—————————————
II) VẬN HÀNH (Progressing)

1) Sign In

Đây là bước quan trọng và phức tạp nhất trong mọi ứng dụng Messessger Protocol, cũng là chủ đề chính của các bài viết này. Bước này đòi hỏi sự đồng nhất giữa SC với chuẩn mã hoá tuân theo quy tắc riêng của mỗi ứng dụng tin nhắn.

Thiết lập socket tới csc.msg.yahoo.com:5050

csc.msg.yahoo.com chỉ là địa chỉ CNAME (Canonical name for an alias), DNS server sẽ xác định host cho csc.msg.yahoo.com và trả về các gói tin chứa thông tin cho biết máy chủ sẽ kết nối đến – Host Address (Cho thấy Yahoo có rất nhiều máy chủ phân tán).

scsc.msg.yahoo.com: type A, class IN, addr 66.163.181.167
scsc.msg.yahoo.com: type A, class IN, addr 66.163.181.168
….
scsc.msg.yahoo.com: type A, class IN, addr 66.163.181.193
….

ymsg_quer

Host có thời gian đáp ứng tốt nhất sẽ được chọn (Lúc đó là Addr: 66.163.181.167)

Client gửi string Username cho Server

0000 3a fb 20 00 18 00 08 00 0f 00 00 00 08 00 45 00 :. ….. ……E.
0010 00 48 28 7a 40 00 80 06 a8 8a 0a 10 27 51 42 a3 .H(z@… ….’QB.
0020 b5 a7 0b b1 13 ba ce 6c 9a 63 9b cc e8 02 50 18 …….l .c….P.
0030 70 1c 9f e5 00 00 59 4d 53 47 00 0f 00 00 00 0c p…..YM SG……
0040 00 57 00 00 00 00 00 46 f5 b9 31 c0 80 76 69 65 .W…..F ..1..vie
0050 74 5f 76 71 c0 80 t_vq..

59 4d 53 47 – YMSG : standard header
00 0f - .. : Version 15, với 2 bytes đệm ở sau là 00 00
00 0c - .. : Packet Length, là độ dài của Content (12 bytes)
00 57 – .W : Service, chữ W (57) ra hiệu cho server trả về kí tự xác nhận (challenge command)
00 00 00 00 – …. : Status
00 46 f5 b9 – .F.. : 4 bytes Session, luôn thay đổi ở mỗi lần giao dịch
31 c0 80 76 69 65 74 5f 76 71 c0 80 – 1..viet_vq.. : 12 bytes nội dung. Mỗi phần tử nội dung (Key, Value) được ngăn cách bởi 2 byte c0 80.
31 là mã ASCII trả về chuỗi (String) 1
c0 80
76 69 65 74 5f 76 71 mã ASCII trả về chuỗi viet_vq
c0 80

Server Response to:
0000 08 00 0f 00 00 00 3a fb 20 00 18 00 08 00 45 00 ……:. …..E.
0010 00 a0 3a b5 40 00 31 06 e4 f7 42 a3 b5 a7 0a 10 ..:.@.1. ..B…..
0020 27 51 13 ba 0b b1 9b cc e8 02 ce 6c 9a 83 50 18 ‘Q…… …l..P.
0030 ff ff 57 02 00 00 59 4d 53 47 00 0f 00 00 00 64 ..W…YM SG…..d
0040 00 57 00 00 00 01 00 5a a9 a7 31 c0 80 76 69 65 .W…..Z ..1..vie
0050 74 5f 76 71 c0 80 39 34 c0 80 77 5e 28 6f 26 34 t_vq..94 ..w^(o&4
0060 5e 28 6f 7c 28 34 2f 6b 25 31 2a 35 2f 75 2d 61 ^(o|(4/k %1*5/u-a
0070 2f 71 2a 68 2d 6f 25 33 2a 70 26 61 2b 6f 7c 76 /q*h-o%3 *p&a+o|v
0080 5e 33 26 28 78 2f 6f 26 64 2d 69 26 6a 26 28 6c ^3&(x/o& d-i&j&(l
0090 2a 71 2a 77 2f 67 5e 6a 2f 6a 29 7c 28 72 2d 61 *q*w/g^j /j)|(r-a
00a0 29 29 29 29 29 c0 80 31 33 c0 80 32 c0 80 )))))..1 3..2..

Để ý đến một cặp khoá mới được server trả về với key 94 là

w^(o&4^(o|(4/k%1*5/u-a/q*h-o%3*p&a+o|v^3&(x/o&d-i&j&(l*q*w/g^j/j)|(r-a)))))

Nhận xét:

- Cố tình thử lại nhiều lần, kể cả cung cấp thông tin login sai cho server, thấy rằng chuỗi kí tự này luôn luôn xuất hiện và thay đổi trong từng session một.
- Mã trả về luôn có số tags đóng bằng số tags mở, các kí tự $, ^, +, %, *, / có vẻ như các phép toán => chuỗi được biểu thị như một biểu thức đại số.
- Đây chắc chắn là một mã hash (token) chứng thực (authetication).

  • ViệtQ

Phần 3

Ta đã nói về chuỗi challenge được gửi trả về w^(o&4^(o|(4/k%1*5… và nghĩ nó như một phép toán số học.

Nhưng thực tế thì không phải là như vậy, các dấu ngoặc ( ) chỉ có mục đích duy nhất là “rắc rối hoá” chuỗi challenge string, trông như một biểu thức phức tạp…

Công việc tạo mã Response sẽ tạo một chuỗi bốc tách từ chữ, số và các “phép toán” của challenge string. Sau đó chúng được biến đổi tiếp bằng các công đoạn dịch bits rất lằng nhằng và phức tạp (trong khuôn khổ 1 bài phân tích Protocol, bài viết không đào sâu vào chi tiết thuật toán). Bên cạnh đó, thuật toán tiếp tục sinh thêm 2 chuỗi mới, 1 chuỗi encoded bằng cách lấy mã YahooBase64 (YB64) của mã MD5 của chuỗi Password; và chuỗi thứ 2 cũng được encoded bằng YB64 của thuật toán MD5 trộn với 1 mã Salt có giá trị “$1$_2S43d5f” (Do Yahoo quy ước)

String regular = YahooBase64(md5(password));
String crypted = YahooBase64(md5(md5Crypt(password, “$1$_2S43d5f”)));

[YahooBase64 là chuẩn format của YMSG (unofficial named). Còn có tài liệu gọi là Mac64. Chuẩn này chỉ khác so với Base64 thông thường ở 3 kí tự "." ,"_" & "-" ứng với "+" , "\" & "=" ở Base64.]

Trong nhiều ứng dụng bảo mật, khi mã hoá MD5 thường kèm theo salt, salt là chuỗi sinh ngẫu nhiên kèm với lần tạo password đầu tiên, và salt hay được lưu trữ ở máy chủ để tránh hacker nếu sniff được đoạn mã MD5 thì cũng không thể fake được vì thiếu mã salt…

Tiếp tục với 2 chuỗi vừa tạo ra, lần lượt mỗi chuỗi kết hợp với chuỗi đầu tiên, dùng các thuật toán SHA-1, gom nhóm bits, dịch bits (mã hoá 2 bytes (== 16bits) bằng 3 chars), và thêm các kí tự “,” “;” ở cuối và “=” ở giữa đoạn string cuối cùng để trông đoạn code như phép gán… 2 chuỗi sau khi encoded có dạng:
(Tham khảo thêm trong các mã nguồn kèm theo bài này)

D=Ci;F=do;m=8C;Y=3a,S=DC;p=21,N=29;S=jn;L=Dj;Y=CB;
O=kA,w=g4,V=a3;L=jC,h=Ej,h=Fa,V=na,E=b3;R=p9,S=jj,

OK, bây giờ client gửi lại giá trị này với key 6 và 96 (service 84), kèm với các vectors:

0: ID
2: ID
2: 1
244: 2097087
148: 180
135: CLIENT_VERSION
1: ID

  • Khi các thông tin đã chính xác, quá trình đăng nhập thành công! (Nick của bạn sẽ phát sáng trên máy người khác)

Nhờ các công đoạn lằng nhằng (monkey around) trên, Yahoo đã không ít lần khiến các 3nd party phải lao đao khi muốn tái hiện lại đoạn code chanllenge của hãng để tích hợp Y!M trong các ứng dụng của họ.

Thử lùi thời gian lại để có cái nhìn rõ hơn về quá trình lao lực với Chanllenge Reponse này của Yahoo!Inc, trong những phiên bản đầu tiên của mình, Yahoo sử dụng đường Http Proxy để tiếp nhận thông tin đăng nhập từ client, tuy nhiên các thông tin gửi đến server đều ở dạng clear text nên rất dễ bị thất lạc thông tin. Sau đó Yahoo! cải tiến bằng cách trước khi password được gửi, nó sẽ bị mã hoá bằng thuật toán MD5 (Dịch vụ webmail trước đó còn sử dụng Java-Script để mã hoá MD5 ngay tại browser). Mặc dù MD5 là thuật toán mã hoá mà đến nay chưa thể decoded nhưng có thể thấy các thông tin gửi lên server sẽ luôn là một hằng số nếu sử dụng theo phương thức này. Mặc dù ngay sau đó, Yahoo! áp dụng trộn thêm chuỗi Salt sinh bởi client trong các lần đăng nhập để giá trị encoded cuối cùng luôn được thay đổi nhưng xem ra thuật toán vẫn rất dễ bị nắm bắt và khai thác.

Ngày 24/6/2004, hãng Trillian tạo ra một ứng dụng 3nd party để kết nối với accounts Y!M, không hỗ trợ các kiểu quảng cáo của Yahoo!. Ngay lập tức bị Yahoo! phản kháng. Từ đó, nhiều cuộc tranh cãi đã nổ ra giữa Yahoo!Inc với các hãng 3nd party khai thác dịch vụ của Yahoo. Và rồi Yahoo quyết tâm thay đổi thuật toán mãnh liệt nhằm ngăn cản công việc nghiên cứu đến từ các tổ chức bên ngoài. Giải thuật mới (đã giới thiệu ở trên) thật sự phức tạp mà đến nay vẫn được Yahoo sử dụng cùng với phiên bản Y!M 9.0 mới nhất. Tuy đã ngăn cản được Trillian trong một thời gian nhất định nhưng cuối cùng, thuật toán đó cũng đã bị cracked và rò rỉ qua mạng Internet cho đến ngày nay. :D

Sau khi đoạn mã hash chính xác đáp trả lại server, quá trình đăng nhập đã thành công mà không cần thêm bất cứ một thông tin nào. Lúc này server sẽ trả về thông tin thêm về tài khoản (Full name, Sex, Virtual IDs, Friends list, Denied list, Unread email…) trong một gói tin bao gồm nhiều YMSG Packets (multiple packets), client cần bóc tách và xử lí từng đoạn phù hợp.

2) Khái quát các dịch vụ khác (Send msg, Status…)
- Mỗi dịch vụ được quy chuẩn bởi Yahoo, ở version 15 có các tags của dịch vụ thông thường sau:

• 0×06 MESSAGE

Format 1 : (status = 0×00000001) Online message
5 : to (yahoo id)
4 : from (yahoo id)
14 : message text
[optional extension]
63 : imvironment name or “;0″
64 : “0″
97 : utf8 encode true/false
Format 2 : (status = 0×00000005) Offline message(s)
31 : “6″ ——–+
32 : “6″ |
5 : to (yahoo id) |
4 : from (yahoo id) | Repeat for each message
15 : Unix timestamp |
14 : message text |
97 : “1″ ——–+
Cài đặt thêm các cặp giá trị (63,0) (64,0) (206,0) với các accounts của hotmail liên thông.

• 0×55 / 0xF1
LIST

89 : Virtual ID
3 : Primier ID
216, 254: Alias ID (First name, Last name)
59 : HTTP cookie Y
59 : HTTP cookie T
59 : HTTP cookie C
3 : yahoo id
100 : “0″
101 : “”
102 : “”
93 : “86400″
149 : base64 style encoded binary
150 : base64 style encoded binary
151 : base64 style encoded binary
65 : Group name
7 : friend ID
(241 : 2) hotmail user
301 : 319
300 : 319
(301 : 319) ignored friends list
(300 : 319) ignored friends list

• 0xF0 UNKNOWN SERVICE (Online + Status ID)

13 : 1 Availble
19: Custom status

• 0×02 LOGOFF

0: ID

nguon: http://vietfov.net

No comments:

Post a Comment