Sự thú vị của việc phân tích cú pháp địa chỉ IP
(blog.dave.tf)-
Bài viết tổng hợp dễ đọc về những điều tác giả học được khi tạo một trình phân tích cú pháp IPv4+v6 nhanh
-
Biểu diễn chính tắc (Canonical)
→ v4 : 192.168.0.1, Dotted Quad của các byte 1 byte
→ v6 : 1:2:3:4:5:6:7:8, Colon-Hex của các từ 2 byte
[IPv6]
- Vì ở giữa thường xuất hiện nhiều số 0, nên dùng
::để lược bỏ một hay nhiều số 0
→ 1:2::3:4 = 1:2:0:0:0:0:3:4
- 32 bit cuối có thể dùng cách biểu diễn Dotted Quad của v4
→ 1:2:3:4:5:6:77.77.88.88 = 1:2:3:4:5:6:4d4d:5858
→ fe80::1.2.3.4 = fe80:0:0:0:0:0:102:304
- Có thêm các trường hợp
::đứng ở đầu/cuối nên phức tạp hơn một chút
→ ::1 = 0:0:0:0:0:0:0:1
→ 1:: = 1:0:0:0:0:0:0:0
→ :: = 0:0:0:0:0:0:0:0
- Mọi trường trong IPv6 Colon-Hex đều là số hex 4 chữ số, có thể lược bỏ số 0 ở đầu
→ :: = 0000:0000:0000:0000:0000:0000:0000:0000
[IPv4]
- Điều thú vị là trước khi cách biểu diễn Dotted Quad cho 32 bit cuối trong IPv6 được chính thức hóa, chưa từng có tài liệu nào tiêu chuẩn hóa chuyện này
→ Vì vậy tiêu chuẩn thực tế (de-facto) trong ngành thường là “4.2BSD có giải thích được không?” và “khi các OS khác sao chép 4.2BSD thì họ đã giữ lại điều gì?”
- Nhưng 4.2BSD hơi kỳ quặc (whacky)
→ 192.168.140.255 = 3232271615 là cùng một giá trị
→ Tức là nếu truy cập http://3232271615 trên Chrome thì nó sẽ tải http://192.168.140.255. Vì đó là một số 4 byte!
→ Dạng bát phân như http://0300.0250.0214.0377 cũng được
→ Vậy thì tất nhiên dạng thập lục phân https://0xc0.0xa8.0x8c.0xff cũng là cùng một địa chỉ
- CIDR (Classless Inter-Domain Routing) cũng ảnh hưởng đến địa chỉ IP
→ Biểu diễn lớp C 192.168.140.255 nếu viết theo lớp B sẽ là http://192.168.36095, còn theo lớp A sẽ là http://192.11046143
→ Vì thế mới có ping 127.1 = 127.0.0.1. Đây không phải là lược bỏ các số 0 lặp như IPv6, mà có nghĩa là host số 1 trong mạng lớp A 127. Tức là số 24 bit có giá trị 1
- Có thể có bao nhiêu số 0 ở trước số của từng Quad?
→ 001.002.003.004? 0000000001.0000000002.0000000003.000000004?
→ (Chrome cũng chấp nhận http://0000000001.0000000002.0000000003.000000004)
→ Lúc này nên đọc các số đó theo bát phân hay thập lục phân? : Các triển khai gần đây đã bỏ cách hiểu bát phân/thập lục phân, và xử lý các số có số 0 ở đầu như thập phân
- Vấn đề số 0 ở đầu này cũng ảnh hưởng đến IPv6
→ 000001::00001.00002.00003.00004 = 1::1.2.3.4, or 1::102:304
→ Hầu hết các parser hiện đại dùng thư viện "parse integer", nên dù có nhiều số 0 ở đầu thì vẫn đều chấp nhận
Tức là để phân tích cú pháp mọi địa chỉ IP, phải tính đến hết đống rắc rối tệ hại này, nhưng...
Trình phân tích cú pháp của tác giả chỉ hỗ trợ chắt lọc ở mức sau
-
Kiểu v4 cổ điển với các số nguyên ngăn cách bằng dấu chấm, cho phép số lượng số 0 ở đầu là không giới hạn
-
Không xử lý biểu diễn lớp A/B và cũng không xử lý bát phân/thập lục phân
-
Cũng không xử lý kiểu biểu diễn mọi thứ bằng một số
uint32duy nhất -
Với IPv6, cho phép kiểu colon-hex chính tắc, kiểu rút gọn
::, và cả cách gắn IPv4 vào 32 bit cuối (IPv4 này vẫn theo các quy tắc ở trên). Số lượng số 0 ở đầu của mỗi trường là không giới hạn
- Ban đầu tác giả thêm cách gắn địa chỉ IPv4 ở cuối để hỗ trợ chuyển đổi dễ dàng từ IPv4 sang IPv6, nhưng trên thực tế hiếm khi thấy. Vì vậy vẫn hỗ trợ, nhưng tác giả cho rằng nó không quá hữu ích
2 bình luận
Ồ, thú vị đấy! Có vẻ có khá nhiều kỹ thuật dễ tận dụng để lách khi tấn công nhỉ!
Tôi lại nghĩ rằng nếu phải dùng những quy tắc phức tạp như thế chỉ để biểu diễn địa chỉ IP thì có phải là đang lãng phí tài nguyên tính toán một cách vô ích không ^^;;