Lỗi phân đoạn trong tràn bộ đệm là gì năm 2024

Lỗi tràn bộ đệm, hẳn là mọi người khi lập trình thì ai cũng gặp phải lỗi này. Tràn bộ đệm xảy ra khi lưu trữ dữ liệu vượt ra ngoài biên của bộ nhớ đệm có chiều dài cố định. Kết quả là dữ liệu có thể bị đè lên các bộ nhớ liền kề. Dữ liệu bị ghi đè có thể bao gồm các bộ nhớ đệm khác, các biến và dữ liệu điều khiển luồng cả chương trình.

Hiện này hầu hết chúng ta đều code các ngôn ngữ bậc cao nên khi xảy ra lỗi tràn bộ đệm thì sẽ dẫn đến chương trình bị crash nên sẽ dễ dàng để fix lỗi. Còn nếu không thì sao?.... Nếu không thì chúc mừng bạn, chương trình của bạn rất có thể sẽ bị hacker tấn công qua lỗi tiềm ẩn này. Và lỗi này thì thường xảy ra ở các ngôn ngữ bậc thấp, chúng ta phải tự quản lý vùng nhớ khi sử dụng các biến ví dụ assemble, C, C++.

Ví dụ tràn bộ đệm

Vừa trên làm một ít khái niệm cơ bản mà ai cũng biết, giờ cùng xem nó tràn như thế nào qua ví dụ với một chương trình bằng ngôn ngữ C nhé :D


# include <stdio.h>

# define val 2019
int main(){
    int key = 0;
    char buf[13];
    printf("&buf: %p, &key: %p\n", buf, &key);
    printf("gia tri can truyen vao key la %d\n", val);
    gets(buf);
    if (key == val){
        printf("Chuc mung ban!\n");
    } else {
        printf("key: %d\n", key);
    }
    return 0;
}

Một chương trình C đơn giản với mục đích nhập giá trị cho mảng buf làm sao để biến key thay đổi và bằng đúng giá trị val cho trước. Nhập buf mà thay đổi key, cái nồi gì thế ?????. Let's exploit it :D.

Cùng chạy xem hiện ra gì nhé.

Lỗi phân đoạn trong tràn bộ đệm là gì năm 2024

Chương trình in ra địa chỉ của 2 biến buf = 0000000062FE30key = 0000000062FE4C Địa chỉ này thì có ý nghĩa gì ???. Địa chỉ chỉ ra vị trí mà biến được sắp xếp trên bộ nhớ. Lấy địa chỉ của key trừ đi địa chỉ của buf ta được kết quả


# include<stdio.h>
int main()
{   
    printf("1111111111111111111111111111%c%c\n",227,7);
    return 1;
}

2. Vậy có nghĩa là biến 2 biến cách nay


# include<stdio.h>
int main()
{   
    printf("1111111111111111111111111111%c%c\n",227,7);
    return 1;
}

3.

Mặc dù mảng buf chỉ có


# include<stdio.h>
int main()
{   
    printf("1111111111111111111111111111%c%c\n",227,7);
    return 1;
}

4kí tự nhưng hãy cùng nhập 28 kí tự vào xem sao nhé :D

Lỗi phân đoạn trong tràn bộ đệm là gì năm 2024
Chương trình vẫn chạy đúng, biến key không bị thay đổi. Cùng nhập kí tự thứ

# include<stdio.h>
int main()
{   
    printf("1111111111111111111111111111%c%c\n",227,7);
    return 1;
}

6 xem có gì xảy ra???

Lỗi phân đoạn trong tràn bộ đệm là gì năm 2024
Bùm.... Biến

# include<stdio.h>
int main()
{   
    printf("1111111111111111111111111111%c%c\n",227,7);
    return 1;
}

7 đã thay đổi giá trị. Như vậy là dữ liệu đã bị tràn sang vùng nhớ của biến


# include<stdio.h>
int main()
{   
    printf("1111111111111111111111111111%c%c\n",227,7);
    return 1;
}

7.

Vậy làm sao để thay đổi đúng giá trại của biến


# include<stdio.h>
int main()
{   
    printf("1111111111111111111111111111%c%c\n",227,7);
    return 1;
}

9 ??? . Kí tự thứ 29 chúng ta vừa điền là `C`0 kết quả `C`1. Và đó cũng là giá trị của kí tự `C`2 tương ứng với `C`3 trong `C`4. Mọi chuyện đơn giản rồi, chúng ta chỉ cần biến đổi số `C`5 về kiểu char là xong. Đầu tiên `C`6 trong kiểu nhị phân. Vì mỗi `C`7 sẽ là `C`8 nên ta tách 8 bit một rồi kiểm tra với bảng mã acsii. `C`9 và `buf`0với kiểu `buf`1. Check trong bảng mã Ascii tương ứng với ... kí tự đặc biệt nên mình không viết được, các bạn check bảng nhé :D..

Kí tự đặc biệt thì mình phải làm thế nào @@. (Lấy ngay phải ví dụ đen thế không biết @@). Không viết không copy được thì chúng ta lại đành phải dùng một chương trình nhỏ để in ra đoạn mã chứa kí tự đặc biệt này.


# include<stdio.h>
int main()
{   
    printf("1111111111111111111111111111%c%c\n",227,7);
    return 1;
}

Ở trên mình có điền sẵn


# include<stdio.h>
int main()
{   
    printf("1111111111111111111111111111%c%c\n",227,7);
    return 1;
}

2 số `C`0 và thêm 2 kí tự char có giá trị Dec là`buf`4 và `buf`5. Cùng ghi giá trị ra file nhé.

Lỗi phân đoạn trong tràn bộ đệm là gì năm 2024

Chương trình trên mình lưu tên là buf`6 sau khi in ra file ta được một số kí tự rất chi là đặc biệt. Giờ thì cùng thực hiện bước cuối cùng, nhập chuỗi kí tự này vào mảng `buf bằng file và chờ đợi kết quả. :D :D

Lỗi phân đoạn trong tràn bộ đệm là gì năm 2024

Bùm bùm .... vậy là biến


# include<stdio.h>
int main()
{   
    printf("1111111111111111111111111111%c%c\n",227,7);
    return 1;
}

7 đã thay đổi giá trị theo ý muốn.

Kết luận

Như vậy chúng ta có thể thấy lỗi tràn bộ đệm khá là nguy hiểm, nó khiến thay đổi luồng chương trình, chương trình bị đổ vỡ... và rất có thể bị kẻ gian khai thác.