Tải bản đầy đủ (.pdf) (20 trang)

Lập trình an tòan (SECURE PROGRAMMING

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.17 MB, 20 trang )

10/23/2019

LOGO

www.themegallery.com
Lập trình an tồn

(SECURE PROGRAMMING)

Nội dung
1

Lập trình an tồn

Tổng quan về lập trình an tồn

2

Tràn bộ đệm

3

Kiểm sốt truy nhập

4

Mã hóa thơng tin

5

Mã hóa đối xứng



6

Giới thiệu chương trình

Lập trình an tồn

1. Tên học phần: Lập trình an tồn (secure
programming).
2. Tồng số tiết: 30 tiết lý thuyết, 30 tiết thực hành
(bài tập nhóm, thảo luận, đồ án)
3. Nơi dụng chương trình: 7 chương

Thực hiện chương trình

Lập trình an tồn

1. Sinh viên nghiên cứu tài liệu.
2. Lên lớp lý thuyết (30 tiết, 10 buổi).
3. Thực hành: làm bài tập nhóm, thảo luận, báo cáo
(30 tiết).

Mã hóa cơng khai
Hàm băm và xác và xác thực thông điệp

1


10/23/2019


Đánh giá

Tài liệu tham khảo

Lập trình an tồn

Lập trình an tồn

1. Điểm chun cần+ thảo luận, báo cáo bài tập
nhóm: 40%

[1] Bài giảng Lập trình an tồn, Ths Lương Ánh
Hồng

2. Điểm thi cuối kỳ: 60%

[2] Giáo trình mã hóa thơng tin, PGS Dương Anh
Đức, TS Trần Minh Triết, ĐHKHTN TP. Hồ Chí Minh
[3] Secure Programming CookBook, John Viega
and Matt Messier
[4] Writing Secure Code, Michael Howard, Devid
LeBlanc.

Chương 1

LOGO

www.themegallery.com
Lập trình an tồn


Nội dung

Lập trình an tồn

1.1. Tầm quan trọng của an tồn - bảo
mật hệ thống.
1.2. Hướng của tiến trình phát triển an
toàn – bảo mật hệ thống phần mềm.
1.3. Các nguyên tắc của an toàn – bảo
mật phần mềm.
Tài liệu tham khảo: Writing Secure Code , Michael Howard,
Devid LeBlanc.

1.4. Các mô hình tấn cơng, đe dọa tính
an tồn – bảo mật phần mềm

2


10/23/2019

1.1. Sự cần thiết các hệ thống phải an toàn –
Lập trình an tồn
bảo mật
 Một hệ điều hành được coi là “an tồn” khi nó
đảm bảo được ba yếu tố chính: Confidentiality
(tuyệt mật), Integrity (tồn vẹn) và Availability
(sẵn sàng).

1.1. Sự cần thiết các hệ thống phải an toàn –

Lập trình an tồn
bảo mật

 Phần mềm có chất lượng phải là phần
mềm an toàn và tin cậy.

 Để hệ thống an tồn địi hỏi rất nhiều cơng sức
trong tất cả giai đoạn phát triển phần mềm, nhất
là giai đoạn lập trình.
 Những sai lầm trong việc lập trình gây ảnh
hưởng tới tính an tồn của hệ thống.

1.1. Sự cần thiết các hệ thống phải an tồn –
Lập trình an tồn
bảo mật

 Một sản phẩm phần mềm khơng an tồn,
có lỗ hổng bảo mật thì chi phí khắc phục,
vá lỗi vơ cùng đắt.
 Một số xu hướng cho an toàn, bảo mật
trong lập trình và kỹ thuật phần mềm trong
tương lai:
 Song hành cùng phát triễn của phần cứng
và công nghệ phần mềm.
 Hội thảo, hợp tác các lực lượng trong lãnh
vực an toàn, bảo mật.

1.1. Sự cần thiết các hệ thống phải an tồn –
Lập trình an tồn
bảo mật

 Đẩy mạnh giáo dục về an toàn và bảo mật
 Xác định trọng tâm của an tồn, bảo mật và phịng
chống các loại tấn cơng theo từng thời điểm thích
hợp
 Sự tấn cơng phá hoại và sự bảo vệ; an tồn phần
mềm song hành phát triển ngày càng tin vi, phức
tạp và nâng cao.
- Nguyên lý 1: phải bảo vệ an tồn tất cả mọi điểm,
tấn cơng chỉ chọn điểm yếu nhất.
- Nguyên lý 2: Tổ chức bảo vệ an toàn trên cơ sở
hiểu biết về các cuộc tấn công; tấn cơng trên cơ
sở tìm các lỗ hõng của an tồn bảo mật

3


10/23/2019

1.1. Sự cần thiết các hệ thống phải an toàn –
Lập trình an tồn
bảo mật

1.2. Xu hướng của tiến trình phát triển của an
Lập trình an tồn
tồn và bảo mật phần mềm

- Nguyên lý 3: Tổ chức bảo vệ phải thường xuyên,
liên tục; tấn công là tùy ý.
- Nguyên lý 4: Tổ chức bảo vệ phải “đúng luật’; cịn
tấn cơng có thể “chơi bẩn”.


 Cải thiện, phát triển an tồn tất cả các pha của
quy trình phần mềm: từ phỏng vấn, thiết kế, cài
đặt và nhất là pha test kiểm tra.
 Tăng cường tuyên truyền, giáo dục về an toàn
và bảo mật thông tin.
 Thiết kế đúng (tin cậy) và an tồn thì sản phẩm
tạo ra (phần mềm) có giá trị và giãm chi phí.
Ngược lại, nếu thiết kế sai, khơng an tồn thì chi
phí khắc phục, sửa chữa, bảo trì vơ cùng tốn
kém.

1.2. Xu hướng của tiến trình phát triển của an
Lập trình an tồn
tồn và bảo mật phần mềm

1. 3. các nguyên tắc của an toàn bảo mật

 Phần mềm có chất lượng chỉ khi phần mềm an
tồn, một code có chất lượng chỉ khi code là an
tồn.
 Pha kiểm thử (test) an toàn là rất quan trọng cho
chất lượng phần mềm. Kiểm thử phải kiểm
chứng được phần mềm khơng có lỗi, khơng thể
bị tấn cơng (an tồn). Ngồi ra kiểm thử cịn phải
kiểm chứng được sẽ an toàn trước các lỗi (lỗ
hỏng) phát sinh và xu hướng tấn công trong
tương lai.

a. Chiến lược SD3: thiết kế an toàn, cài đặt mặc

định an toàn, chuyển giao huấn luyện an toàn.
b. Các nguyên tắc của an toàn bảo mật:
 Học từ các lỗi, các sai lầm
 Cực tiểu hóa các bề mặt tấn cơng
 Phịng thủ, bảo vệ theo chiều sâu
 Phân quyền các đặc quyền ít nhất
 Sử dụng an tồn hơn mặc định
 Ln giả thuyết là hệ thống ngồi là khơng an
tồn.
 Có kế hoạch cho thất bại
 Luôn chỉnh lại cho đúng các lỗi an tồn bảo mật

Lập trình an tồn

4


10/23/2019

1. 4. Mơ hình các đe dọa an tồn bảo mật

Lập trình an tồn

 Thiết kế an tồn thơng qua mơ hình đe dọa an
tồn bảo mật.
 Các kỹ thuật an toàn – bảo mật phần mềm
 Xác thực: là tiến trình, chính yếu là đảm bảo tính
tồn vẹn và kiểm chứng tính tồn vẹn của tiến
trình khác.
 Có nhiều giao thức xác thực trong hệ điều hành

window. Có một giao thức xác thực được xây
dựng trong phần mềm, một số mà người sử dụng
thực hiện xác thực theo yêu cầu của OS.
Cơ bản có các bước xác thực là:
o Xác thực cơ bản
o Xác thực theo danh sách

LOGO

www.themegallery.com
Lập trình an tồn

Tràn bộ đệm
(Buffer overun)

1. 4. Mơ hình các đe dọa an tồn bảo mật

Lập trình an tồn

o Dạng thức (mẫu) xác thực cơ bản: khơng có dạng
thức chung. Có thể tham khảo qua đoạn code xác
thức ASP để đọc username và password:
<%
Dim strUsername, strPwd As String
strUsername = Request.Form("Username")
strPwd = Request.Form("Pwd")
If IsValidCredentials(strUserName, strPwd) Then
' Cool! Allow the user in!
' Set some state data to indicate this
Else

' Oops! Bad username and password
Response.Redirect "401.html"
End If
%>

Nội dung
Chương

Lập trình an tồn

2.1 Tràn stack.
2.2 Tràn heap.
2.3 Lổi định dạng chuỗi
2.4 Kích thước bộ đệm của mã Unicode và
Ansi không tương hợp.
2.5 Ngăn chặn tràn bộ đệm

5


10/23/2019

2.1. Tràn stack

Lập trình an tồn

Tổ chức bộ nhớ của Stack/Heap

2.1. Tràn stack
Ví dụ: đoan chương trình


2.1. Tràn stack

Lập trình an toàn

 Tràn stack xãy ra khi buffer được khai báo trong
stack bị ghi đè bởi dữ liệu lớn hơn buffer được khai
báo.
 Các biến khai báo trong stack trã về địa chỉ của
hàm gọi.
 Thông thường, hệ thống (hệ điều hành) khơng kiểm
tra luồng nhập (như hàm strcpy)
 Ví dụ đoạn code làm tràn stack

Lập trình an tồn

2.1. Tràn stack

Lập trình an tồn

Minh họa bộ nhớ của đoạn mã thực hiện và Stack data

void checkserial()
{
char sn[16];
scanf(‘%s‛, sn);
}
int main()
{
checkserial();

int i= 7;
return 0;
}

6


10/23/2019

2.1. Tràn stack

2.1. Tràn stack

Lập trình an tồn

 Khi hàm checkserial thực hiện xong, lệnh RET sẽ nạp

lại giá trị 128 tại địa chỉ 401 trong stack vào con trỏ
lệnh IP để quay về lại lệnh i= 7.
 Nếu trong hàm checkserial, người sử dụng nhập vào
chuỗi ít hơn 16 ký tự thì chương trình hoạt động bình
thường, tuy nhiên nếu người sử dụng nhập vào chuỗi
16 ký tự trở lên thì lúc này ơ nhớ 401 sẽ bị đè bởi ký tự
thứ 16, tình trạng tràn bộ đệm xảy ra. Lúc này khi lệnh
RET của hàm checkserial thực hiện, con trỏ lệnh IP sẽ
có 1 giá trị khác chứ khơng phải là 128, do đó lệnh i= 7
sẽ khơng được thực hiện.
 Hacker có thể lợi dụng điều này để tiến hành các hoạt
động phá hoại.


Lập trình an tồn

Vi dụ 2: tràn stack
void checkserial()
{
char sn[16];
printf(‘\nEnter a serial number\n‛);
scanf(‚%s‛, sn);
if (!strncmp(sn‚’S123N456‛, 8))
{
printf(‚Serial number is correct‛);
}
}
int main()
{
checkserial();
int i=7;
return 0;

}

2.1. Tràn stack

Lập trình an tồn

 Lợi dụng lỗi tràn bộ đệm hacker sẽ tìm cách nhập
vào một chuỗi gì đó (khác “S123N456”), mà
chương trình vẫn in ra câu “Serial number is
correct”.
 Ví dụ, nhập chuỗi:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAⱠ^R@
 Đây chính là cách thức mà sâu Code Red vào
năm 2001 đã sử dụng để lây nhiễm.

2.2. Tràn heap

Lập trình an tồn

Tương tự như tràn stack. Tuy nhiên nhiên, tràn
heap sự tấn cơng có thể ghi tùy ý các thơng tin
vào vị trí của ứng dụng mà nó đã truy cập.
Có một số hệ điều hành và chip xử lý bảo vệ,
không cho tấn công stack; heap khơng bị tấn
cơng.
Ví dụ sau, minh họa làm tràn heap.

7


10/23/2019

2.2. Tràn heap
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
class BadStringBuf
{
public:
BadStringBuf(void)
{

m_buf = NULL;
}
~BadStringBuf(void)
{
if(m_buf != NULL)
free(m_buf);
}
void Init(char* buf)
{
m_buf = buf;
}

void SetString(const char* input)
{
strcpy(m_buf, input);
}
const char* GetString(void)
{
return m_buf;
}
private:
char* m_buf;
};
BadStringBuf* g_pInput = NULL;
void bar(void)
{
printf("Augh! I've been hacked!\n");
}

2.3. Lổi định dạng chuỗi


2.2. Tràn heap

Lập trình an tồn

void BadFunc(const char* input1,
const char* input2)
{
char* buf = NULL;
char* buf2;
buf2 = (char*)malloc(16);
g_pInput = new BadStringBuf;
buf = (char*)malloc(16);
g_pInput->Init(buf2);
strcpy(buf, input1);
g_pInput->SetString(input2);
printf("input 1 = %s\ninput 2 =
%s\n", buf, g_pInput ->GetString());
if(buf != NULL)
free(buf);
}

Định dạng sai dạng thức chuỗi (string) không xãy ra
tràn bộ đệm nhưng cũng dẫn đến vấn đề tương tự.
Xét ví dụ:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
typedef void (*ErrFunc)(unsigned
long);

void GhastlyError(unsigned long
err)
{
printf("Unrecoverable error! - err
= %d\n", err);
exit(-1);
}

int main(int argc, char* argv[])
{
char arg1[128];
char arg2[4] = {0x0f, 0x10, 0x40,
0};
int offset = 0x40;
memset(arg1, 0xfd, offset);
arg1[offset] = (char)0x94;
arg1[offset+1] = (char)0xfe;
arg1[offset+2] = (char)0x12;
arg1[offset+3] = 0;
arg1[offset+4] = 0;
printf("Address of bar is %p\n",
bar);
BadFunc(arg1, arg2);
if(g_pInput != NULL)
delete g_pInput;
return 0;
}

2.3. Lổi định dạng chuỗi


Lập trình an tồn

void RecoverableError(unsigned
long err)
{
printf("Something went wrong, but
you can fix it - err = %d\n",err);
}
void PrintMessage(char* file,
unsigned long err)
{
ErrFunc fErrFunc;
char buf[512];
}

if(err == 5)
{
fErrFunc = GhastlyError
}
else
{
fErrFunc =
RecoverableError;
}
snprintf(buf, sizeof(buf)-1,
"Cannot find %s", file);
printf("%s", buf);
printf("\nAddress of fErrFunc is
%p\n", &fErrFunc);
fprintf(stdout, buf);

printf("\nCalling ErrFunc %p\n",
fErrFunc);
fErrFunc(err);

Lập trình an tồn

Lập trình an toàn

void foo(void)
{
printf("Augh! We've been
hacked!\n");
}
int main(int argc, char* argv[])
{
FILE* pFile;
printf("Address of foo is %p\n",
foo);
pFile = fopen(argv[1], "r");
if(pFile == NULL)
{
PrintMessage(argv[1],
errno);
}

8


10/23/2019


2.3. Lổi định dạng chuỗi
else
{

}

Lập trình an tồn

2.4.Kích thước bộ đệm mã
Unicode và Ansi không tương hợp.

Tràn bộ nhớ đệm trong trường hợp này hơi giống
cơ chế Windows platforms
Tràn bộ nhớ đệm khi ta xếp ngẫu nhiên số lượng
các phần tử theo kích thước byte trong bộ nhớ
đệm Unicode.
BOOL GetName(char *szName)
 Ví dụ:
{

printf("Opened %s\n",
argv[1]);
fclose(pFile);

}
return 0;

}

2.4.Kích thước bộ đệm mã

Unicode và Ansi khơng tương hợp.

Lập trình an tồn

WCHAR wszUserName[256];
// Convert ANSI name to Unicode.
MultiByteToWideChar(CP_ACP, 0,
szName,
-1,
wszUserName,
sizeof(wszUserName));
// Snip

Lập trình an tồn

Lập trình an tồn

Giá trị của tham số sizeof(wszUserName)?
256? Sai
Đúng là 512 (vì size(character) là 2).
Tràn buffer (khai báo là 256).
 Đoạn code đúng là:
MultiByteToWideChar(CP_ACP,
0,
szName,
-1,
wszUserName,
sizeof(wszUserName) / sizeof(wszUserName[0])
);


2.5. Chèn câu lệnh SQL (SQL Injection)

 Hê DBMS thường sử dụng câu truy vấn SQL để gửi
yêu cầu thao tác dữ liệu đến hệ quản trị CSDL. Hệ
quản trị CSDL xử lý và gửi trả lại dữ liệu kết quả cho
phần mềm.
 Câu SQL không được biên dịch sẵn, chỉ khi nào phần
mềm ứng dụng tạo câu SQL và gửi cho DBMS thì
DBMS mới biên dịch và thực hiện câu SQL. Trong
quá trình tạo câu SQL, phần mềm ứng dụng
 thường sử dụng tham số do người dùng nhập vào.
Đây chính là đặc điểm mà hacker có thể lợi dụng,
tiến hành thay đổi câu SQL theo ý riêng của hacker.

9


10/23/2019

Lập trình an tồn

2.5. Chèn câu lệnh SQL (SQL Injection)

 Ví dụ: Để quản lý người dùng, người lập trình tạo

một table Users(username, password, email).

 Và thiết kế một form như sau (ví dụ dùng C# và
ADO.NET).


Lập trình an tồn

2.5. Chèn câu lệnh SQL (SQL Injection)

 Nếu người dùng nhập vào user là admin và password
là abc thì câu SQL là:
 SELECT * FROM Users WHERE Username=’admin’
AND Password=’abc’

 Câu SQL này hoạt động bình thường theo đúng ý
người lập trình.
 Tuy nhiên nếu hacker nhập vào user là admin’ -- và bỏ
trống password thì câu SQL trở thành:
SELECT * FROM Users WHERE Username=’admin’ --’
AND Password=’’

Lập trình an tồn

2.5. Chèn câu lệnh SQL (SQL Injection)
 Code của nút Login:

private void btnLogin_Click(object sender, EventArgs e)
{
string sql = " SELECT * FROM Users " +
" WHERE Username = '" + txtUser.Text + "' AND " +
" Password = '" + txtPass.Text + "'";
SqlCommand cmd = new SqlCommand(sql, strConnect);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read()){
// login ok

}
else{
// login failed
}
dr.Close();
}

Lập trình an tồn

2.5. Chèn câu lệnh SQL (SQL Injection)

 Trong SQL Server dấu – nghĩa là chú thích. Như vậy
câu SQL trên cho ra kết quả là một record có
username là admin. Điều đó nghĩa là hacker đăng
nhập với quyền admin mà không cần biết password.
 Ở đây dấu ’ và dấu -- mà hacker nhập vào đã làm thay
đổi cấu trúc câu SQL mà người lập trình khơng ngờ
tới.
 Nếu hacker nhập user là ’; DELETE FROM Users -thì câu SQL trở thành:
SELECT * FROM Users WHERE Username=’’; DELETE
FROM Users --’ AND Password=’’
 Bây giờ có hai câu SQL, câu thứ nhất truy xuất bảng
Users và câu thứ 2 xóa tồn bộ bản Users, chương
trình bị khóa khơng đăng nhập được.

10


10/23/2019


Lập trình an tồn

2.5. Chèn câu lệnh SQL (SQL Injection)

Để chống lại tấn công SQL Injection, chúng ta sử
dụng 2 cách:
 Xử lý các ký tự đặt biệt như dấu „ trong dữ liệu
nhập trước khi tạo câu SQL
 Sử dụng parameter để truyền tham số cho câu
SQL.

2.7. Tràn số


2.6. Ngăn chặn tràn stack

Lập trình an tồn

 Dịng code đầu tiên để bảo vệ là chắc chắn
nhất tuy có vẻ ít cần thiết cho viết code an
tồn.
 Ln phải kiểm tra các luồng dữ liệu đầu vào
của hàm; không truy cập các dữ liệu từ ngồi
của hàm mà khơng kiểm tra (ln xem các dữ
liệu ngồi là kẻ thù tấn cơng hàm).
 Khi lập trình trong các ngơn ngữ Java, C#..., ta
sử dụng “safe” để trình biên dịch tự động kiểm
tra lỗi tràn stack.

Lập trình an tồn


Ví dụ: Giá trị số nguyên
int main(int argc, char *argv[])
{
unsigned char total;
total = strlen(argv[1])+strlen(argv[2])+1;
char *buff = (char *)malloc(total);
strcpy(buff, argv[1]);
strcat(buff, argv[2]);
printf("%s",buff);
return 0;
}

11


10/23/2019

Ví dụ: chuyển kiểu số nguyên
int main()
{
unsigned int l=0xffffffff;
char c = -1;
if (c == l)
{
printf("Why is -1 = 4,294,967,295???\n");
}
return 0;
}


1. Biểu diễn số nguyên

1. Biểu diễn số nguyên
 Có 2 cách biểu diễn số nguyên: biểu diễn bù 1 và biểu diễn bù
 Ví dụ:

2. Miền giá trị số nguyên

 Có 2 cách biểu diễn số nguyên: biểu diễn bù 1 và biểu diễn bù
 Ví dụ:

12


10/23/2019

Các vấn đề xãy ra lỗi
 Integer Overflow
Khi giá trị số nguyên tăng lớn giá trị cận trên (nhỏ hơn cận
dưới) miền giá trị của kiểu số nguyên
 Sign Errors
Xãy ra khi chuyển số nguyên từ số nguyên có dấu sang số
nguyên không dấu
 Truncation Errors
Xãy ra khi chuyển số nguyên lớn sang số nguyên nhỏ hơn
(số byte biểu diễn)

Ví dụ: Ép kiểu (chuyển kiếu số
nguyên)


13


10/23/2019

Ví dụ: chuyển kiểu số nguyên

Chiến lược giãm lỗi, rũi ro

int main()
{
unsigned char tol=0xff;
char tt=tol;
printf("%d\n%d",tol,tt);
return 0;
}

LOGO

www.themegallery.com
Lập trình an tồn

Kiểm sốt tuy nhập
(Access Control)
Tài liệu tham khảo:
Secure Programming Cook , John Viega,Mtt Messier

Nội dung
Chương


Lập trình an tồn

 3.1 Cơ chế kiểm soát truy nhập trên
Unix/Linux.
 3.2 Cơ chế kiểm soát truy nhập trên
Windows.
 3.3 Hạ thấp quyền truy nhập của tiến trình.
 3.4 Xóa file an tồn
 3.5 Hạn chế quyền truy nhập trên file
 3.6 Khóa file
 3.7 Tạo file tạm
 3.8 Hạn chế truy nhập đến hệ thống file

14


10/23/2019

3.1. Cơ chế kiểm sốt truy nhập
Chương
trên Unix/ Linux

Lập trình an toàn

 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 có sở hữu (owner): chủ sở hữu (user),
nhóm sở hữu (group) và một tập các quyền truy
nhập.
 Có 3 mức quyền truy nhập file: mức chủ (User:

u), mức nhóm người dùng (Group: g), mức người
dung khác (Other/All:a).
 Mỗi tiến trình có ba quyền: effective user id, real
user id, saved user id.
 Có ba loại quyền truy cặp:
Đọc (read: r)
Ghi (write: w)

3.1. Cơ chế kiểm soát truy nhập
Chương
trên Unix/ Linux

Lập trình an tồn

 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
đó.

3.1. Cơ chế kiểm sốt truy nhập
Chương
trên Unix/ Linux

Lập trình an tồn


 Thực thi (execute: x)
 Mỗi file sẽ có ba nhóm quyền tương ứng với: user
id, group id, và other.
 drwxr-xr-x
12 root root
4096
Oct 23
2000 LinuxVN.com
 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.

3.1. Cơ chế kiểm sốt truy nhập
Chương
trên Unix/ Linux

Lập trình an tồn

 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ư 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

đó.

15


10/23/2019

3.2. Cơ chế kiểm sốt truy nhập
Chương
trên Windows

Lập trình an toàn

 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 số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ó
tồ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.

3.2. Cơ chế kiểm sốt truy nhập
Chương

trên Windows

Lập trình an tồn

 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ó tồ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.

3.2. Cơ chế kiểm sốt truy nhập
Chương
trên Windows

Lập trình an toàn

 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_ALL

Full control

GENERIC_WRITE

The ability to write to or modify the object


GENERIC_EXECUTE The ability to execute the object (applies primarily to files)

3.3. Hạ thấp quyền truy nhập của
Chương
tiến trình

Lập trình an tồn

 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).

16


10/23/2019

3.3. Hạ thấp quyền truy nhập của
Chương
tiến trình


Lập trình an tồn

 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.

3.4.
ChươngXóa file an tồn

Lập trình an toàn

 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 }};

3.4.
Chương

Xóa file an tồn

Lập trình an tồ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
fflush() nếu sử dụng thư viện C.

3.5. Hạn chế quyền truy nhập
Chương
trên file

Lập trình an tồn

 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 <sys/types.h>
#include <sys/stat.h>
mode_t umask(mode_t

mask);

17


10/23/2019

Chương

3.6. Khóa file

Lập trình an tồn

 Tiến trình muốn kiểm sốt truy nhập trên một phần
của file hay tồ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:

Chương

3.6. Khóa file

Lập trình an tồn


 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.
 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ộ.

Chương

3.6. Khóa file

Lập trình an tồn

 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.
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ộ.

Chương

3.6. Khóa file

Lập trình an tồn

 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[1024];
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_ATTRIBUTE_NORMAL, 0);

18


10/23/2019

Chương


3.6. Khóa file

Lập trình an tồn

ReadFile(fileHandle,buff,128,&bytesRead,0);
buff[bytesRead] = 0;
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);

3.7. Tạo file tạm

Chương

Lập trình an tồn

 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.
 Ví dụ
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);

3.7. Tạo file tạm

Chương

Lập trình an tồn

 Ứ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.

3.7. Tạo file tạm

Chương

Lập trình an tồn

 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.
 GetTempPath() 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

19


10/23/2019

3.7. Tạo file tạm

Chương

Lập trình an tồn

 Ví dụ
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);

3.8. Hạn chế truy nhập đến hệ


Chương

thống file

3.8. Hạn chế truy nhập đến hệ

Chương

thống file

Lập trình an tồn

 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.

Lập trình an tồn

VD:
#include <unistd.h>
chroot("/new/root/directory");
chdir("/");


20



×