Cũng giống như PNG, JPEG và DOC là các loại tệp hợp lệ, polyglot là sự kết hợp của hai loại tệp khác nhau. Ví dụ: Phar + JPEG (tệp lưu trữ PHP và tệp JPEG), GIFAR (tệp Gif và Rar) Javascript + JPEG,….
Tham gia kênh Telegram của AnonyViet 👉 Link 👈 |
Các ứng dụng chỉ cho phép một số loại tệp nhất định trên các tính năng như tải tệp lên và không cho phép các loại tệp khác như tệp .php hoặc .js vì chúng có thể cho phép kẻ tấn công tải lên các tệp độc hại trên ứng dụng. Các ứng dụng thực hiện kiểm tra đuổi file bằng phần mở rộng kép (.jpg.php) hoặc sử dụng byte rỗng trong phần mở rộng (.php%00.jpg), tên tệp (.htaccess, .config,…) và nếu chữ ký của tệp được tải lên cũng phù hợp với loại nội dung của nó.
Ứng dụng khác nhau sử dụng các phương pháp khác nhau và polyglot có thể được sử dụng để bỏ qua một số kiểm tra xác thực này.
Kiến trúc JPEG
Hình ảnh JPEG được biểu diễn dưới dạng một chuỗi các phân đoạn trong đó mỗi phân đoạn bắt đầu bằng header. Mỗi header bắt đầu bằng một số byte. Payload theo header là khác nhau tùy theo loại header. Các loại điểm đánh dấu JPEG phổ biến như được liệt kê bên dưới:
0xffd8: “Start of Image”, 0xffe0: “Application Default Header”, 0xffdb: “Quantization Table”, 0xffc0: “Start of Frame”, 0xffc4: “Define Huffman Table”, 0xffda: “Start of Scan”, 0xffd9: “End of Image”
Mỗi tệp nhị phân chứa một vài header. Chúng rất quan trọng đối với tệp vì chúng xác định thông tin cụ thể của tệp. Hầu hết các header được theo sau bởi thông tin độ dài. Điều này cho chúng ta biết phân đoạn cụ thể đó dài bao nhiêu.
Phần đầu của header hình ảnh chứa FF D8. Nếu chúng ta không nhìn thấy nó, chúng ta có thể cho rằng đây là một tệp khác. Một điểm đánh dấu quan trọng khác là FF D9 cho biết phần cuối của hình ảnh.
Để làm cho payload trông giống như một tệp JPEG hợp pháp, chúng ta sẽ thêm độ dài của header, header nhận xét, các byte rỗng vào pad và sau đó là vectơ tấn công javascript.
Giả sử vectơ tấn công là một lỗ hổng XSS */=alert(“XSS”)/*
Chuyển nó thành hệ thập lục phân sẽ như thế này.
Payload trong hex:
2A 2F 3D 61 6C 65 72 74 28 22 58 53 53 2E 22 29
Chúng ta có thể sử dụng một trình soạn thảo hex để đưa javascript vào metadata của hình ảnh. Điều này hoạt động được vì các trình duyệt diễn giải code khi chúng hiển thị hình ảnh thành HTML.
Mình đã nhận được một image test.jpg và dưới đây là hexdump của test.jpg. Với sự trợ giúp của trình soạn thảo ghex, chúng ta sẽ thay thế một số ký tự hex và lưu chúng.
Như chúng ta biết FF D8 là phần bắt đầu của hình ảnh, hai byte tiếp theo đại diện cho hai byte sắp tới, 00 10 đại diện cho độ dài của tiêu đề JPEG tương đương với số thập phân là 16 byte.
Thời gian tiêm
Chúng ta sẽ đưa payload vào giữa FF E0 và FF DB. Hãy bắt đầu với 2F 2A, là đại diện hex của /*
Chúng ta vừa thay thế 00 10 trước đây bằng 2F 2A và tương đương thập phân của hex 2F 2A là 12074 byte. Vì vậy, bây giờ header hình ảnh được thay đổi từ 16 byte thành 12074 byte.
Từ ảnh chụp màn hình ở trên, chúng ta có thể thấy kích thước của payload là 18 byte, vì vậy chúng ta phải xóa các byte còn lại bằng null là 12074–16–18 = 12040 byte.
Các lệnh trên sẽ đọc test.jpg, chèn payload vào giữa 2F 2A FF DB thay đổi hệ lục phân vào bộ đệm, thêm 12040 byte rỗng và ghi nó vào tệp test_new.jpg. Bây giờ trong trình soạn thảo ghex đóng thẻ comment trước FF D9
Code to execute image as javascript:-<script charset="ISO-8859-1" src="test_new.jpeg">
Trên Firefox khi sử dụng bộ ký tự UTF-8, nó sẽ làm hỏng polyglot khi được đưa vào dưới dạng tập lệnh. Vì vậy, để tập lệnh hoạt động, chúng ta cần chỉ định bộ ký tự ISO-8859–1 trên thẻ script và nó thực thi tốt.
Và đây là khi test trên trình duyệt.
Polyglot javascript/jpeg của chúng ta đã hoạt động rồi đó.
Cập nhật: Mozilla đã sửa lỗi này trong Firefox 51 và các phiên bản sau.