Nhận diện định dạng file qua magic bytes và phát hiện đuôi tệp giả mạo
Công cụ đọc 64 byte đầu của tệp ngay trong trình duyệt, so với bảng 99 chữ ký định dạng rồi cho biết tệp thật sự là gì. Nếu đuôi tệp không khớp chữ ký, chẳng hạn tệp đặt tên .pdf mà bên trong là mã thực thi Windows, cảnh báo đỏ hiện ngay. Bạn cũng có thể dán trực tiếp chuỗi hex để tra mà không cần tệp.
Tính năng nổi bật
- Đọc đúng 64 byte đầu bằng file.slice, phần nội dung còn lại không bao giờ được đưa vào bộ nhớ và không rời khỏi máy bạn
- Đối chiếu đuôi tệp với đuôi hợp lệ của chữ ký nhận được, lệch thì cảnh báo đỏ, khớp thì xác nhận xanh
- Cảnh báo mức nặng riêng khi tệp mang đuôi tài liệu hoặc ảnh nhưng chữ ký thật là mã thực thi
- Ô dán chuỗi hex nhận cả dạng liền, dạng cách nhau, dạng có tiền tố 0x và không phân biệt chữ hoa chữ thường
- Hex dump chuẩn với cột offset, mười sáu byte mỗi dòng và cột ASCII thay byte không in được bằng dấu chấm
- Bảng tra cứu 99 chữ ký chia bảy nhóm, có ô tìm theo tên định dạng, đuôi tệp, MIME hoặc chuỗi hex
- Xử lý được chữ ký hai đoạn như WebP, WAV, AVI, AVIF nên không nhầm bốn byte RIFF hay ftyp dùng chung
- Liệt kê mọi chữ ký cùng khớp và xếp mục cụ thể nhất lên đầu theo độ dài chuỗi và độ sâu offset
Vì sao cần biết định dạng thật thay vì tin vào đuôi tệp
Đuôi tệp chỉ là mấy ký tự trong tên, ai cũng đổi được trong hai giây và không có gì bên trong tệp ràng buộc nó phải đúng. Trong khi đó, gần như mọi định dạng nhị phân nghiêm túc đều tự đánh dấu bằng một chuỗi byte cố định ở đầu, và đó mới là thứ trình đọc thật sự dựa vào. Khoảng cách giữa hai thứ này sinh ra hai loại rắc rối hằng ngày. Loại thứ nhất là nhầm lẫn vô hại nhưng tốn thời gian: ảnh tải từ web lưu thành .jpg mà thật ra là PNG hoặc WebP nên trình dựng video từ chối nhận, tệp xuất từ phần mềm cũ đặt đuôi .xls mà bên trong là XML hoặc CSV nên thư viện đọc bảng tính báo lỗi khó hiểu. Loại thứ hai nghiêm trọng hơn: tệp đính kèm đặt tên là hóa đơn.pdf nhưng hai byte đầu là 4D5A, tức tệp thực thi Windows đội lốt tài liệu. Kiểm tra chữ ký cho câu trả lời dứt khoát trong vài giây, không cần cài công cụ dòng lệnh và không phải tải tệp lên máy chủ nào.
Lợi ích khi sử dụng
- Biết chắc tệp là gì trước khi mở, đặc biệt với tệp đính kèm hoặc tệp lấy từ nguồn lạ
- Phát hiện đuôi giả mạo mà trình quản lý tệp của hệ điều hành không hề báo
- Không phải cài công cụ dòng lệnh hay tải tệp lên máy chủ của ai, mọi thứ chạy trong trình duyệt
- Chỉ đọc 64 byte nên tệp cỡ nào cũng cho kết quả ngay, khác hẳn việc phải quét toàn bộ nội dung
- Bảng 99 chữ ký kèm ghi chú dùng được như tài liệu tra cứu khi viết bộ kiểm tra tệp tải lên
- Hex dump giúp tự kiểm chứng thay vì phải tin kết quả một cách mù quáng
Cách nhận diện định dạng file bằng chữ ký
- 1Ở thẻ Tải file lên, chọn tệp cần kiểm tra. Trình duyệt chỉ đọc 64 byte đầu, phần còn lại không được chạm tới nên tệp nặng vài gigabyte cũng cho kết quả tức thì.
- 2Đọc khối Kết quả nhận diện: tên định dạng hiện bằng chữ lớn, kèm chuỗi hex khớp, offset, MIME type và danh sách đuôi hợp lệ.
- 3Nhìn dải màu ngay bên dưới: xanh nghĩa là đuôi khớp chữ ký, đỏ nghĩa là lệch, đỏ đậm nghĩa là tệp mang đuôi vô hại nhưng chữ ký thật là mã thực thi.
- 4Nếu chỉ có chuỗi byte chứ không có tệp, chuyển sang thẻ Dán chuỗi hex rồi dán vào. Chuỗi có hay không có khoảng trắng và tiền tố 0x đều được.
- 5Đối chiếu hex dump ở cột bên phải để tự xác nhận, hoặc gõ tên định dạng, đuôi tệp hay chuỗi hex vào ô tìm kiếm của bảng tra cứu bên dưới để xem toàn bộ chữ ký cùng ghi chú.
Magic bytes là gì và vì sao hệ điều hành tin chữ ký hơn tên tệp
Magic bytes, còn gọi là file signature, là một chuỗi byte cố định mà định dạng tự đặt ở vị trí biết trước trong tệp, thường là ngay đầu. PNG mở đầu bằng 89 50 4E 47 0D 0A 1A 0A, trong đó năm mươi, bốn mươi sáu và bốn mươi bảy chính là ba chữ P, N, G ở mã ASCII, còn byte 89 cố ý vượt ngưỡng ASCII để lộ ra nếu đường truyền làm hỏng bit cao, và cặp 0D 0A 1A 0A bắt lỗi phần mềm tự tiện đổi ký tự xuống dòng. Cách thiết kế đó cho thấy chữ ký không chỉ để nhận dạng mà còn để tự kiểm tra tệp có nguyên vẹn không. Nhân Linux dùng đúng nguyên tắc này khi chạy tệp: gặp hai byte 23 21, tức dấu thăng và dấu chấm than, nó đọc tiếp dòng đầu để biết gọi trình thông dịch nào, còn gặp 7F 45 4C 46 thì nạp tệp như một chương trình ELF. Không có bước nào nhìn tới đuôi tệp cả, vì trên Unix đuôi tệp vốn chỉ là quy ước cho con người. Lệnh file trên Unix làm cùng việc đó ở tầng người dùng, dựa trên thư viện libmagic với cơ sở dữ liệu vài nghìn quy tắc mô tả chuỗi byte, vị trí và mặt nạ bit. Trình duyệt cũng có cơ chế riêng gọi là MIME sniffing, chuẩn hóa trong đặc tả MIME Sniffing của WHATWG, để đoán kiểu nội dung khi máy chủ khai báo sai hoặc không khai báo, và đó là lý do một ảnh gắn nhầm Content-Type vẫn hiển thị được.
Vấn đề định dạng vỏ ZIP: DOCX, XLSX, APK, EPUB đều là ZIP
Đây là giới hạn khiến người mới dùng công cụ nhận diện chữ ký hay bối rối nhất. Bốn byte 50 4B 03 04 nghĩa là tệp bắt đầu bằng một bản ghi cục bộ của kho ZIP, và hàng loạt định dạng hiện đại chọn ZIP làm lớp vỏ. Bộ Office từ bản 2007 trở đi dùng OOXML, tức DOCX, XLSX, PPTX, đều là kho ZIP chứa các tệp XML. Bộ OpenDocument gồm ODT, ODS, ODP cũng vậy. EPUB là ZIP, APK của Android là ZIP, JAR của Java là ZIP, KMZ của bản đồ là ZIP, tiện ích XPI của Firefox là ZIP, gói IPA của iOS cũng là ZIP. Nghĩa là chữ ký chỉ nói với bạn lớp vỏ chứ không nói nội dung bên trong, và một công cụ chỉ đọc bốn byte đầu sẽ trả về ZIP cho tất cả. Muốn đi xa hơn thì phải mở kho ra và đọc tên mục đầu tiên: OOXML luôn có mục [Content_Types].xml, ODF và EPUB đặt mục mimetype ở đầu và cố ý không nén để công cụ đọc được ngay, APK có AndroidManifest.xml, JAR có thư mục META-INF với tệp MANIFEST.MF. Ý nghĩa thực tế nằm ở chỗ khác: nếu hệ thống của bạn cho phép tải lên tệp .docx và chỉ kiểm tra chữ ký ZIP là xong, thì kẻ tấn công có thể gửi một tệp APK hoặc một kho ZIP chứa bất cứ thứ gì với tên đuôi .docx và vượt qua bộ kiểm tra. Ngược lại, bộ quét chỉ nhìn đuôi tệp cũng bị lừa theo chiều còn lại, vì một kho ZIP đổi tên thành .docx trông y hệt tệp Word hợp lệ ở tầng tên.
Đuôi tệp giả mạo và những rủi ro bảo mật đi kèm
Trò lừa cổ điển nhất là đặt tên tệp thực thi thành hoadon.pdf. Windows theo mặc định vẫn ẩn đuôi các loại tệp đã biết, nên người nhận nhìn thấy hoadon.pdf, bấm đúp, và thứ chạy lên là một chương trình. Công cụ này bắt được ngay vì hai byte đầu là 4D 5A chứ không phải 25 50 44 46. Biến thể tinh vi hơn là double extension, đặt tên hoadon.pdf.exe để phần đuôi thật bị đẩy ra ngoài rìa tên dài. Tinh vi hơn nữa là chèn ký tự điều khiển U+202E, tức right-to-left override, vào giữa tên: chuỗi lưu trên đĩa là hoadon\u202Efdp.exe nhưng phần mềm hiển thị đảo ngược đoạn sau thành hoadon exe.pdf, mắt thường không phân biệt nổi. Không mẹo nào trong số đó đổi được byte đầu tệp, nên kiểm tra chữ ký vẫn phát hiện. Với hệ thống nhận tệp tải lên, bài học rút ra là chỉ kiểm tra đuôi tệp hoặc chỉ tin trường Content-Type mà trình duyệt gửi lên đều không đủ, vì cả hai đều do phía người dùng kiểm soát hoàn toàn. Bộ kiểm tra tối thiểu nên có bốn lớp: đọc vài chục byte đầu để xác nhận chữ ký nằm trong danh sách trắng, đặt giới hạn dung lượng để chặn tệp nén phồng, sinh lại tên tệp phía máy chủ thay vì dùng tên người dùng gửi, và với ảnh thì render lại bằng thư viện xử lý ảnh để loại bỏ mọi dữ liệu lạ nhét trong phần siêu dữ liệu. Ngoài ra, thư mục chứa tệp tải lên không nên được cấu hình cho phép thực thi.
Giới hạn của phương pháp nhận diện bằng chữ ký
Đọc byte đầu là cách nhanh và đáng tin, nhưng nó không phải câu trả lời cho mọi tình huống, và biết trước giới hạn giúp bạn không kết luận sai. Thứ nhất, không phải chữ ký nào cũng nằm ở đầu tệp. TAR đặt chuỗi ustar ở offset 257 vì phần trước đó là tên tệp trong khối tiêu đề, DICOM đặt chuỗi DICM ở offset 128 sau vùng đệm dành riêng, ISO 9660 đặt CD001 ở offset 32.769 vì mười sáu khối đầu để trống cho vùng hệ thống, siêu khối ext4 nằm ở offset 1080, còn ảnh đĩa DMG của macOS đặt chuỗi koly ở 512 byte cuối chứ không phải ở đầu. Công cụ chỉ đọc 64 byte đầu như trang này không thể thấy chúng, đó là cái giá phải trả cho việc không đụng tới nội dung tệp. Thứ hai, nhiều định dạng không có magic bytes nào cả. TXT, CSV, JSON, YAML, HTML hay mã nguồn đều là văn bản thuần, còn Protocol Buffers cố ý không có chữ ký vì byte đầu là một varint mã hóa số hiệu trường nên thay đổi theo từng thông điệp, muốn đọc phải biết trước lược đồ. Thứ ba là polyglot file, những tệp được dựng cố ý để hợp lệ ở hai định dạng cùng lúc, chẳng hạn tệp vừa là GIF vừa là JavaScript chạy được, hoặc vừa là PDF vừa là kho ZIP. Với chúng thì câu hỏi tệp này là định dạng gì không có một đáp án duy nhất. Cuối cùng, chữ ký khớp chỉ nói vài byte đầu đúng chuẩn, hoàn toàn không bảo đảm phần còn lại nguyên vẹn hay giải mã được.
Khác gì với công cụ kiểm tra hash và công cụ tra MIME type trên site
Ba công cụ này hay bị gộp làm một nhưng trả lời ba câu hỏi khác hẳn nhau, và chọn nhầm thì vừa mất thời gian vừa không có câu trả lời cần tìm. Trang bạn đang đọc trả lời câu hỏi tệp này thực chất là định dạng gì, bằng cách đọc đúng 64 byte đầu rồi so với bảng chữ ký. Vì khối lượng dữ liệu đọc là cố định, tệp một megabyte hay tệp mười gigabyte đều cho kết quả trong cùng khoảng thời gian, và phần nội dung còn lại không bao giờ được chạm tới. Công cụ tại /vi/tools/file-hash-checker trả lời câu hỏi khác: hai tệp này có giống hệt nhau không, hoặc bản tải về có đúng bản mà nơi phát hành công bố không. Nó tính SHA-1 hoặc SHA-256 trên toàn bộ nội dung tệp, nên mọi byte đều phải chạy qua hàm băm và thời gian xử lý tỉ lệ thuận với dung lượng. Đổi lại, kết quả nhạy tới mức đổi một bit cũng ra chuỗi băm hoàn toàn khác, còn tên tệp và đuôi tệp thì không ảnh hưởng gì. Công cụ tại /vi/tools/mime-type-lookup trả lời câu hỏi thứ ba: đuôi này ứng với MIME type nào để khai báo Content-Type cho đúng khi phục vụ tệp qua HTTP. Nó tra theo bảng ánh xạ và hoàn toàn tin vào tên tệp, không mở nội dung ra xem. Cách phối hợp hợp lý là dùng trang này khi nghi ngờ tệp bị đổi tên, dùng bộ kiểm tra hash khi cần chứng minh tính toàn vẹn, và dùng bảng MIME khi cấu hình máy chủ hoặc viết phần tải xuống.
Câu hỏi thường gặp (FAQ)
Công cụ có tải toàn bộ file của tôi lên máy chủ không?
Không. Công cụ chỉ đọc 64 byte đầu của file ngay trong trình duyệt bằng file.slice, không đọc phần nội dung còn lại và không gửi file đi đâu. Không có lệnh gọi mạng nào trong quá trình nhận diện, nên tắt mạng rồi dùng vẫn chạy bình thường.
Vì sao chỉ đọc 64 byte mà không đọc cả tệp cho chắc?
Vì gần như mọi chữ ký hữu ích đều nằm trong vài byte đầu, và đọc cố định 64 byte nghĩa là tệp mười gigabyte cũng cho kết quả nhanh như tệp mười kilobyte. Cái giá phải trả là các chữ ký nằm sâu hơn, như TAR ở offset 257 hay DICOM ở offset 128, sẽ không được phát hiện khi tải tệp lên.
Tôi mở file .docx mà công cụ báo là ZIP, có phải nhận diện sai không?
Không sai. DOCX, XLSX, PPTX, ODT, EPUB, APK, JAR, KMZ, XPI đều là kho ZIP nên dùng chung chữ ký 50 4B 03 04. Muốn biết chính xác là loại nào phải mở kho ra và đọc tên mục đầu tiên: [Content_Types].xml cho OOXML, mimetype cho ODF và EPUB, AndroidManifest.xml cho APK.
Cảnh báo đỏ khi đuôi không khớp chữ ký nghĩa là file có mã độc phải không?
Không hẳn. Rất nhiều trường hợp lệch là do vô tình, chẳng hạn ảnh WebP tải về bị lưu thành .jpg. Nhưng nếu tệp mang đuôi tài liệu hay đuôi ảnh mà chữ ký thật là mã thực thi Windows hoặc ELF thì đó là dấu hiệu nguy hiểm rõ ràng, khi đó đừng mở tệp và hãy kiểm tra lại nguồn gửi.
Dán chuỗi hex thì cần định dạng thế nào?
Kiểu nào cũng được. Ô nhập chấp nhận chuỗi liền như 89504E470D0A1A0A, chuỗi cách nhau như 89 50 4E 47 0D 0A 1A 0A, chuỗi có tiền tố 0x, và không phân biệt chữ hoa chữ thường. Chỉ cần tổng số ký tự hex là số chẵn vì mỗi byte cần đúng hai ký tự.
Vì sao một chuỗi byte lại khớp nhiều chữ ký cùng lúc?
Vì nhiều định dạng chia nhau phần đầu giống nhau. Tệp MP4 khớp cả hộp ftyp chung lẫn thương hiệu cụ thể, tệp WebP khớp cả bốn byte RIFF chung với WAV và AVI. Công cụ liệt kê tất cả kết quả và đưa mục cụ thể nhất lên đầu, tính theo độ dài chuỗi hex và độ sâu offset.
File của tôi không khớp chữ ký nào, có nghĩa là file hỏng không?
Thường là không. Các định dạng văn bản thuần như TXT, CSV, JSON, YAML, HTML hay mã nguồn vốn không có magic bytes nên không bao giờ khớp. Protocol Buffers cũng cố ý không có chữ ký. Chỉ khi bạn chắc chắn tệp phải thuộc một định dạng nhị phân cụ thể mà lại không khớp thì mới nên nghi tệp hỏng.
Chữ ký khớp có bảo đảm file mở được không?
Không. Chữ ký chỉ nói vài byte đầu đúng chuẩn của định dạng đó. Phần thân tệp vẫn có thể bị cắt cụt do tải dở, bị hỏng do lỗi ổ đĩa, hoặc dùng bộ mã hóa mà phần mềm của bạn không hỗ trợ. Muốn kiểm tra tính toàn vẹn thì phải so chuỗi băm với bản gốc.
Công cụ này khác gì kiểm tra hash file?
Khác về cả câu hỏi lẫn khối lượng công việc. Trang tại /vi/tools/file-hash-checker tính SHA-1 hoặc SHA-256 trên toàn bộ nội dung tệp để so khớp hai bản có giống hệt nhau không, nên thời gian xử lý tỉ lệ với dung lượng. Trang này chỉ đọc 64 byte đầu để biết định dạng và hoàn toàn không quan tâm phần còn lại.
Công cụ này khác gì tra MIME type?
Trang tại /vi/tools/mime-type-lookup ánh xạ đuôi tệp sang MIME type theo bảng, tức là nó tin vào tên tệp bạn đưa và không mở nội dung ra xem. Trang này làm ngược lại: bỏ qua tên tệp, đọc byte thật rồi mới kết luận, và chính vì vậy nó phát hiện được đuôi giả mạo.
Trên máy tính có lệnh nào làm việc tương tự không?
Trên Linux và macOS có lệnh file, dựa trên thư viện libmagic với cơ sở dữ liệu vài nghìn quy tắc mô tả chuỗi byte và vị trí. Thêm tham số để lấy riêng MIME type nếu cần. Trên Windows có thể dùng lệnh xem nội dung dạng hex trong PowerShell, nhưng bạn phải tự đối chiếu chuỗi byte với bảng chữ ký.
Polyglot file là gì và công cụ xử lý ra sao?
Đó là tệp được dựng cố ý để hợp lệ ở hai định dạng cùng lúc, ví dụ vừa là GIF vừa là JavaScript chạy được, hoặc vừa là PDF vừa là kho ZIP. Với chúng, câu hỏi tệp này là định dạng gì không có đáp án duy nhất. Công cụ vẫn báo chữ ký khớp ở byte đầu, nhưng đó chỉ là một trong các danh tính của tệp.
Từ khóa liên quan
- nhận diện định dạng file
- magic bytes là gì
- file signature identifier
- kiểm tra đuôi file có đúng không
- bảng chữ ký file signature
- file giả đuôi pdf thành exe
- hex dump online
- đọc byte đầu file
- chữ ký PNG 89504E47
- chữ ký ZIP 504B0304
- docx xlsx apk đều là zip
- phân biệt docx và zip
- lệnh file trên linux libmagic
- mime sniffing trình duyệt
- kiểm tra file upload an toàn
- double extension attack
- ký tự RTL override tên file
- polyglot file là gì
- offset chữ ký ISO TAR DICOM
- công cụ kiểm tra định dạng file online
