Tài liệu Các lỗi khác - an toàn thông tin

  • Số trang: 16 |
  • Loại file: PDF |
  • Lượt xem: 295 |
  • Lượt tải: 0
Khotailieu

Đã đăng 199 tài liệu

Mô tả:

Điều kiện đua ● Xảy ra khi nhiều tiến trình (tiểu trình) truy cập và sửa đổi cùng một dữ liệu vào cùng lúc, kết quả phụ thuộc vào thứ tự truy cập Dữ liệu chung Tiến trình 1 Tiến trình 2 Điều kiện đua ● Để tận dụng lỗi, người ta thường chạy thật nhiều tiến trình ngoài để “đua” với tiến trình bị lỗi → chữ “đua” ● Còn được gọi là TOC/TOU ● Xét ví dụ: ● if (access[argv[1], R_OK) == 0) { f = fopen(argv[1], “r”); } Điều kiện đua ● Giữa hàm access() và fopen() có một khoảng thời gian nhỏ ● ● CALL CMP JNZ PUSH PUSH CALL access EAX, 0 ... ... ... fopen Hệ điều hành có thể chuyển qua tiến trình khác ở giữa các lệnh đó Điều kiện đua Điều kiện đua ● access() và fopen() nhận tên file ● Cùng một tên nhưng có thể là 2 file khác nhau ● ● symlink Do đó, ta sẽ tận dụng bằng cách: ● ● ● ● Chỉ symlink đến tập tin có thể đọc được Chỉ symlink đến tập tin không có quyền đọc nhưng chương trình bị lỗi có thể đọc được Lập lại 2 việc này liên tục Song song đó, ta sẽ chạy chương trình bị lỗi và truyền tên symlink vào Điều kiện đua ● ● ● Điều kiện đua thường gặp ở các ứng dụng xử lý file, ứng dụng mạng, database, ứng dụng đa tiểu trình, ứng dụng web Ứng dụng web đặc biệt dễ mắc phải vì vừa đa tiến (tiểu) trình, vừa truy cập database, vừa truy cập file Cách dễ nhất để tránh lỗi là tuần tự hóa truy cập vào tài nguyên chung ● ● File lock, database isolation level Spinlock, mutex, futex, CRITICAL_SECTION, semaphore Điều kiện đua ● Cẩn thận với deadlock ● ● Xét ví dụ: ● ● Khi hai hoặc nhiều tiến (tiểu) trình chờ nhau lock(resource1) lock(resource2) dosomething() lock(resource2) lock(resource1) dosomething() Cách khắc phục ● ● ● Luôn luôn chú ý về thứ tự truy cập Lock phải được cấp theo cùng thứ tự, và mở theo thứ tự ngược Lock phải được mở ngay sau khi đã dùng xong Dư một ● ● Là trường hợp đặc biệt của tràn bộ đệm trong đó chỉ tràn duy nhất 01 byte Xét ví dụ ● void vuln(char *arg) { char buf[8]; strcpy(buf, arg); } void main(int argc, char **argv) { vuln(argv[1]); } Dư một ● Giả sử argv[1] dài 8 ký tự ● Khi vào vuln() thì biến buf sẽ chứa 8 ký tự này ● Và ký tự kết thúc (NUL) sẽ lem ra ngoài ● Ký tự \x00 này lem vào ô chứa EBP cũ ● ● Trong phần kết thúc của vuln(), POP EBP vì thế sẽ khiến EBP mang giá trị XXXXXX00 Trong phần kết thúc của main(), MOV ESP, EBP sẽ khiến ESP có giá trị XXXXXX00 Dư một ● ● ● ● Sau đó POP EBP sẽ làm ESP tăng thêm 4 Cuối cùng RET sẽ lấy giá trị hiện tại trên đỉnh ngăn xếp để quay về → lỗi xảy ra trong vuln() nhưng tận dụng trong main() Hai điểm cần chú ý: ● Giá trị EBP mới sẽ nhỏ hơn giá trị EBP đã lưu ● Và do đó có thể chỉ tới phần ngăn xếp trong vuln() Giả sử biến buf có địa chỉ tận cùng là 00 → cơ hội EBP chỉ tới buf sẽ cao → địa chỉ trở về của main() sẽ là từ địa chỉ của biến buf + 4 Dư một Dư một Dư một ● Yêu cầu phải đạt để tận dụng được lỗi ● ● ● Ngăn xếp của vuln() không bị phá (nội dung biến buf không bị mất đi) Vùng nhớ kiểm soát được phải nằm “gần” với giá trị EBP cũ, chỉ được khác byte thấp Cách khắc phục lỗi như với lỗi tràn bộ đệm Tràn số nguyên ● ● ● ● ● Số nguyên trong máy tính được biểu diễn ● Ở dạng bù 2 ● Có dấu, hoặc không dấu Giá trị âm lớn nhất cũng có thể là giá trị dương cao nhất Số có dấu bị lệch về giá trị âm (-128 → 127) Hiện tượng quay vòng (127 + 1 = -128, 255 + 1 = 0) Kích thước kiểu dữ liệu ảnh hưởng quan trọng (255 kiểu short là -1 kiểu char) Tràn số nguyên ● ● Tràn số nguyên xảy ra khi giá trị số nằm ngoài phạm vi biểu diễn của kiểu dữ liệu Xét ví dụ: ● ● ● ● int i; i = atoi(argv[1]); if (i <= 0x1000) fgets(buf, i, stdin); atoi() trả về số nguyên có dấu Tham số thứ 2 của fgets() là kiểu số nguyên không dấu Nếu argv[1] là số âm thì sẽ gây tràn Tràn số nguyên ● Xét ví dụ: ● int i = -maxint; int j = -1; printf(“%d\n”, i / j); ● i là số âm nhất (giả sử -128) ● j là -1 ● Khi thực hiện phép chia sẽ ra số 128, nhưng 128 vượt quá phạm vi biểu diễn (127) → crash
- Xem thêm -