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

  • 16 trang
  • file: .pdf

đang tải dữ liệu....

Tài liệu bị giới hạn, để xem hết nội dung vui lòng tải về máy tính.

Tải xuống - 16 trang

Nội dung text: Các lỗi khác - an toàn thông tin

Đ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 access
CMP EAX, 0
JNZ ...
PUSH ...
PUSH ...
CALL 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
● Khi hai hoặc nhiều tiến (tiểu) trình chờ nhau
● Xét ví dụ:
● lock(resource1) lock(resource2)
lock(resource2) lock(resource1)
dosomething() 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