Bài giảng Lập trình an toàn - Chương 2: Kiểm soát truy nhập - Lương Ánh Hoàng
• Trên Unix/Linux tất cả các tài nguyên đều được coi là file: tệp tin, ổ đĩa, bộ nhớ, thiết bị.
• Mỗi file kiểm soát bởi user id và group id.
• Mỗi tiến trình có ba quyền: effective user id, real user id, saved user id. Effective user id được sử dụng trong phần lớn các kiểm tra.
• Mỗi tiến trình cũng thuộc về ba nhóm: effective group id, real group id, saved group id.
• Có ba loại quyền
• Đọc (read)
• Ghi (write)
• Thực thi (execute)
• Mỗi file sẽ có ba nhóm quyền tương ứng với: user id, group id, và other.
-rwxr-xr-x 1 Luong Anh Hoang None 17964 Aug 28 23:45 test.exe
• Khi tiến trình tạo một file hoặc tài nguyên, hệ thống sẽ gán user id và group id cho file mới đó bằng effective user id và effective group id của tiến trình.
• Khi tiến trình truy nhập một file hoặc tài nguyên, hệ thống sẽ lần lượt so sánh user id, group id của tiến trình và file và chọn ra tập quyền tương ứng. Nếu không khớp thì lớp quyền thứ 3 sẽ được sử dụng.
• Mỗi file cũng có thể có 3 bit đặc biệt
• Sticky. Nếu bit này được thiết lập, người dùng sẽ không thể xóa hay đổi tên file của người khác nằm trong thưc mục mà người dùng quản lý. Mặc định là không được thiết lập.
• Setuid: Bit này liên quan đến quá trình tạo một tiến trình mới. Nếu bit này được thiết lập, tiến trình được tạo từ file này sẽ không kế thừa quyền từ tiến trình cha, mà sẽ có quyền từ user id của chính file đó.
• Setgid:
• Đối với file thực thi, nếu bit này được thiết lập thì một tiến trình mới được tạo sẽ có quyền từ groupd id của file đó chứ không kế thừa từ tiến trình cha (tương tự Setuid).
• Đối với thưc mục, nếu bit này được thiết lập thì các file tạo trong thư mục này sẽ có groupd id của thư mục cha, chứ không kế thừa từ tiến trình tạo ra file đó.
Tóm tắt nội dung tài liệu: Bài giảng Lập trình an toàn - Chương 2: Kiểm soát truy nhập - Lương Ánh Hoàng
Chương 2. Kiểm soát truy nhập Access Control Lương Ánh Hoàng hoangla@soict.hut.edu.vn Nội dung Cơ chế kiểm soát truy nhập trên Unix/Linux Cơ chế kiểm soát truy nhập trên Windows Hạ thấp quyền truy nhập của tiến trình Xóa file an toàn Hạn chế quyền truy nhập trên file Khóa file Tạo file tạm Hạn chế truy nhập đến hệ thống file Trên Unix/Linux tất cả các tài nguyên đều được coi là file: tệp tin, ổ đĩa, bộ nhớ, thiết bị.... Mỗi file kiểm soát bởi user id và group id. Mỗi tiến trình có ba quyền: effective user id, real user id, saved user id. Effective user id được sử dụng trong phần lớn các kiểm tra. Mỗi tiến trình cũng thuộc về ba nhóm: effective group id, real group id, saved group id. Có ba loại quyền Đọc (read) Ghi (write) Thực thi (execute) Mỗi file sẽ có ba nhóm quyền tương ứng với: user id, group id, và other. -rwxr-xr-x 1 Luong Anh Hoang None 17964 Aug 28 23:45 test.exe Khi tiến trình tạo một file hoặc tài nguyên, hệ thống sẽ gán user id và group id cho file mới đó bằng effective user id và effective group id của tiến trình. Khi tiến trình truy nhập một file hoặc tài nguyên, hệ thống sẽ lần lượt so sánh user id, group id của tiến trình và file và chọn ra tập quyền tương ứng. Nếu không khớp thì lớp quyền thứ 3 sẽ được sử dụng. • Mỗi file cũng có thể có 3 bit đặc biệt Sticky. Nếu bit này được thiết lập, người dùng sẽ không thể xóa hay đổi tên file của người khác nằm trong thưc mục mà người dùng quản lý. Mặc định là không được thiết lập. Setuid: Bit này liên quan đến quá trình tạo một tiến trình mới. Nếu bit này được thiết lập, tiến trình được tạo từ file này sẽ không kế thừa quyền từ tiến trình cha, mà sẽ có quyền từ user id của chính file đó. Setgid: Đối với file thực thi, nếu bit này được thiết lập thì một tiến trình mới được tạo sẽ có quyền từ groupd id của file đó chứ không kế thừa từ tiến trình cha (tương tự Setuid). Đối với thưc mục, nếu bit này được thiết lập thì các file tạo trong thư mục này sẽ có groupd id của thư mục cha, chứ không kế thừa từ tiến trình tạo ra file đó. Windows sử dụng ACL: Access Control List để phân quyền tài nguyên. Các tài nguyên của Windows: file, registry, mutex, event, IPC... được kiể’m soát thông qua DACL và SACL. DACL là danh sách các ACE, mỗi ACE là một luật quy định một quyền hạn cụ thể’. DACL rỗng tương đương với việc tất cả mọi người có toàn quyền truy nhập tới đối tượng. Mỗi ACE bao gồm 3 thông tin: SID: Đại diện cho một user hay một group trong hệ thống Quyền truy nhập Giá trị boolean tương ứng với cho phép hay không cho phép. Các quyền truy nhập TÊN Diễn giải DELETE The ability to delete the object READ_CONTROL The ability to read the object's security descriptor, not including its SACL SYNCHRONIZE The ability for a thread to wait for the object to be put into the signaled state; not all objects support this functionality WRITE DAC The ability to modify the object's DACL WRITE OWNER The ability to set the object's owner GENERIC_READ The ability to read from or query the object GENERIC_WRITE The ability to write to or modify the object GENERIC_EXECUTE The ability to execute the object (applies primarily to files) GENERIC ALL Full control Ví dụ ACE DENY GENERIC_ALL Everyone: Cấm mọi quyền với group Everyone ALLOW GENERIC_WRITE Marketing: Cho phép nhóm group Marketing được quyền ghi Mỗi đối tượng đều có một Owner, chính là người tạo ra đối tượng. Owner có toàn quyền với đối tượng bất kể trong DACL có cấm hay không. Owner có thể’ bị chiếm bởi user khác. 2.3 Hạ thấp quyền truy nhập của tiến trình Nếu một tiến trình có đặc quyền cao, thực hiện các thao tác nguy hiểm => cần hạ thấp quyền trước khi thực hiện. Tiến trình có thể’ kiểm tra real user id, real group id bằng lệnh getuid (), getgid(). Đây là các đặc quyền kế thừa từ tiến trình cha. Tiến trình có thể’ kiể’m tra effective user id và effective group id bằng lệnh geteuid() và getegid(). Đây thường là user id có đặc quyền cao hơn (do được khởi chạy từ super user, hoặc các bit setuid được bật). Tiến trình từ bỏ đặc quyền bằng việc thiết lập group mới chính là real user id qua lệnh setgroups(): Thiết lập lại nhóm của tiến trình. setegid(): Thiết lập lại effective group id của tiến trình. seteuid(): Thiết lập lại effective user id của tiến trình. Xóa file an toàn Thông thường, một file sau khi xóa sẽ được hệ điều hành đánh dấu là xóa, nội dung chưa hoàn toàn bị loại bỏ trên đĩa. Giải pháp Ghi đè thông tin khác nhiều lần lên đĩa. Ghi đè dữ liệu ngâu nhiên nhiều lần lên đĩa. Ghi đè sử dụng mẫu định sẵn lên đĩa. Sau mỗi chu kỳ ghi, sử dụng fsync để đồng bộ với đĩa, vô hiệu hóa cơ chế cache. Hoặc lệnh fflushf) nếu sử dụng thư viện C. Một vài mẫu được sử dụng static unsigned char single_pats[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; static unsigned char triple_pats[6][3] = { { 0x92, 0x49, 0x24 }, { 0x49, 0x24, 0x92 }, { 0x24, 0x92, 0x49 }, { 0x6d, 0xb6, 0xdb }, { 0xb6, 0xdb, 0x6d }, { 0xdb, 0x6d, 0xb6 } }; Hạn chế quyền truy nhập trên file Unix/Linux sử dụng umask cho mỗi tiến trình để vô hiệu hóa một vài bit khi tiến trình tạo file. Hàm fopen, open luôn luôn tạo file với quyền 666. Giả sử tiến trình muốn tạo file với quyền 666: requested_permissions = 0666; actual_permissions = requested_permissions & ~umask( ); Ứng dụng thay đổi umask bằng hàm umask() trước khi thực hiện lời gọi tạo file. #include #include mode_t umask(mode_t mask); Khóa file Tiến trình muốn kiểm soát truy nhập trên một phần của file hay toàn bộ file để’ tránh xung đột khi có nhiều tiến trình cùng truy nhập trên file. Unix/Linux cung cấp cơ chế khóa mềm: Mọi tiến trình đều có quyền giành được khóa và thao tác trên file, tuy nhiên không phải tiến trình nào cũng tuân thủ theo khóa và có thể’ phá hỏng dữ liệu của tiến trình khác. Windows thực hiện vấn đề này tốt hơn bằng khóa cứng. Có hai loại khóa: Shared Lock: Cho phép các tiến trình khác (kể cả tiến trình giành được khóa) đọc nhưng không được ghi vào một phần đã khóa của file. Exclusive Lock : Cấm tất cả các tiến trình khác không được đọc hay ghi vào phần đã khóa của file. Tiến trình giành được khóa có quyền đọc hoặc ghi vào file. Khóa file Các hàm khóa file trên Windows LockFile, UnlockFile: Khóa và mở khóa đồng bộ, sẽ không trở về đến khi giành được khóa hoặc mở được khóa. LockFileEx, UnlockFileEx: Khóa và mở khóa đồng bộ hoặc bất đồng bộ. Khóa file cũng có thể xác định lúc tạo lập/truy nhập file thông qua hàm CreateFile. Đoạn chương trình sau sẽ mở một file để’ đọc với chế độ Shared Lock. char buff[i024]; DWORD bytesRead = 0; HANDLE fileHandle = NULL; fileHandle = CreateFile(L”C:\\SecureProgramming\\Test.txt”, GENERIC_READ|GENERIC_WRITE, file_share_read|file_share_Write, 0, OPEN_ALWAYS, FILE_ATTRI BUtE_NORMAL, 0); Khóa file VD (tiếp) ReadFile(fileHandle,buff,128,&bytesRead,0); buff[bytesRead] = o; printf("File content:%s\n",buff); LockFile(fileHandle,0,0,100,0); // Exclusive Lock printf("File is locked, press any key to unlock...\n"); getch(); UnlockFile(fileHandle,0,0,100,0); printf("File is unlocked\n"); getch(); CloseHandle(fileHandle); Tạo file tạm ■ ■ Ứng dụng tạo file tạm để lưu trữ thông tin tạm thời của chương trình. File tạm nên được tạo lập một cách an toàn, và xóa khi kết thúc chương trình. Trên unix/linux: Hàm mkstemp() có thể’ sử dụng để’ tạo file tạm với tên ngẫu nhiên. Ứng dụng cần xóa file theo tên, ngay sau lời gọi mkstemp để đảm bảo không tiến trình nào truy nhập được. Sau khi tiến trình kết thúc một cách bình thường/không bình thường, file tạm sẽ không thể’ truy nhập được nữa. VD char szPath[] = “fileXXXXXX"; int fd; fd = mkstemp(szPath); unlink(szPath); printf("Temperary file created, press any key to continue..."); write(fd,"Hello",5); close(fd); Tạo file tạm ■ ■ Trên Windows: Không có hàm tương đương mkstemp() GetTempFileName() sinh tên file ngẫu nhiên nhưng dễ đoán. GetTempPathQ lấy đường dẫn đến thư mục tạm của người dùng hiện tại. Tạo file bằng hàm CreateFile với hai thuộc tính FILE_ATTRIBUTE_TEMPORARY và FILE_FLAG_DeLETE_ON_CLOSE VD HANDLE fileHandle = NULL; fileHandle = CreateFile(L"C:\\SecureProgramming\\Tmp.txt", gEnerIC_read | generic_wriTe, file_share_reAd | file_share_write, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_TEMPORARY| FILE_FLAG_DELETE_ON_CLOSE, 0); 2.8 Hạn chế truy nhập đến hệ thống file Trên Unix/Linux, ứng dụng có thể tự giới hạn phạm vi truy nhập hệ thống tệp tin của mình bằng lệnh chroot() Sau khi gọi chroot(): Tiến trình không thể mở rộng phạm vi truy nhập bằng lệnh chroot lần nữa.. Tiến trình chỉ có thể thu hẹp hơn nữa phạm vi truy nhập của mình. Tiến trình phải chủ động gọi thêm chdir() để lệnh chroot có hiệu lực. VD: #include chroot(”/new/root/directory”); chdir(”/”);
File đính kèm:
- bai_giang_lap_trinh_an_toan_chuong_2_kiem_soat_truy_nhap_luo.docx
- secureprogramming_2_2207_505051.pdf