Khái niệm lỗ hổng Format String – phần 1

1. MỘT SỐ KHÁI NIỆM :

– Format string: là hành động định dạng đầu ra cho kiểu dữ liệu như integer, float, char …

Ví dụ

#include<stdio.h>
int main(){
char x=”A”;
printf(“%d”,x);return 0;
}

Đầu ra của chương trình sẽ là “A 65″.

Việc định dạng đầu ra ở đây là in ra kí tự x dưới 2 dạng là char và int. Ta có kết quả như trên là do khi in gặp “%c” chương trình sẽ hiểu là in ra dạng kí tự ASCII ứng với giá trị ‘A’ và in ra “A”, còn khi gặp %d thì chương trình sẽ hiểu là in ra giá trị nguyên của ‘A’ trong bảng ASCII và in ra “65”.

Format String attack: là hành động tấn công dựa vào lỗi định dạng chuỗi nó xảy ra khi một dữ liệu dạng chuỗi được nhập vào nhưng được hàm thực thi coi như là một lệnh. Nhờ cách này mà kẻ tấn công có thể truy nhập trái phép vào ngăn xếp và thay đổi dữ liệu trong đó hoặc làm cho chương trình bị treo.

Format Function: là chuyển đổi định dạng hàm trong ngôn ngữ C.Nhiệm vụ của nó là chuyển đổi những biến trong chương trình ra thành các chuỗi mà chúng ta có thể hiểu được.

Format String Parameter: là kiểu định dạng của chuỗi đầu vào nào đó đại diện cho một số hàm chuyển đổi Format string.

2.CƠ BẢN VỀ FORMAT STRING:

a.Kiểu định dạng:

Thông số                                              Đầu ra
% p                           Trỏ tới địa chỉ chứa giá trị của biến
% d                           Số thập phân
% c                           Đầu ra là một kí tự hoặc 1 số
%u                           Số thập phân không dấu
% x                           Dạng số hexa 0-F
%s                           Đầu ra là một chuỗi kí tự
% n                           Đếm độ dài của chuỗi nhập vào

Một số kiểu đặc biệt:

         %n: Đối số được sử dụng như một con trỏ trỏ đến một số nguyên và số lượng kí đầu ra được lưu trữ trong địa chỉ của con trỏ được trỏ đến bởi các đối số trên()

        %s:Các đối số được sử dụng như một con trỏ trỏ đến một chuỗi mà chuỗi này thay thế cho đầu ra

        %x: Đọc dữ liệu từ stack

        %a\$n hay %a\$x là để hiển thị giá trị chứa ở vị trí a nào đó

Ví dụ chúng ta có một đoạn code đơn giản như sau:

20

Kết quả chương trình sau khi chạy:

18

 

b.Cách lưu trữ và lấy dữ liệu trong ngăn xếp

19-223x300

Hình trên cho chúng ta thấy một cách chi tiết chiều lưu các biến vào trong ngăn xếp và chiều lấy các biến ra như thế nào. Để hiểu rõ hơn chúng ta thử chạy một đoạn mã đơn giản sau:

Format string phần 1

Đầu tiên là ta biên dịch chương trình vừa code ở trên :

15

Khi chạy chương trình có hiện một cảnh báo do mình dùng trình dịch gdb nên nó cảnh báo là thiếu định dạng chuỗi-đây là một cách đơn giản giúp chúng ta phát hiện lỗi format string.

Ta chạy thử chương trình :  ./rmt hi   hiện ra “hi” vậy là chương trình không có lỗi và chạy bình thường

Tiếp theo chúng ta thử chạy chương trình với 3 tham số đầu vào khác nhau và xem thử kết quả:

17

Trường hợp đầu tiên không hiện ra gì vì ta không nhập vào gì cả.Trường hợp thứ 2 nó hiện ra kí tự mà ta đánh vào từ bàn phím đến trường hợp thứ 3 nó hiện ra những đoạn mã hexa nào đó.

Nhìn lại vào những dòng mà chúng ta code chúng ta chỉ khai báo một biến agrv[1] cho nên khi ta dùng kiểu định dạng là %4x thì chương trình không thấy biến thứ 2 lưu trong stack nên nó sẽ tìm các dữ liệu trong stack và hiển thị nó ra ngoài như chúng ta thấy trên hình

Chính vì đặc điểm này kẻ tấn công sẽ cung cấp một số đặc tính kỹ thuật về định dạng không có đối số nào tương ứng trên stack và giá trị của stack được sử dụng chính là vị trí của giá trị đó điều này rất dễ dẫn đến việc tiết lộ thông tin.Vậy nên khi lập trình chúng ta nên chú ý cẩn và xem lại kỹ code để tránh mắc lỗi format string. Ở phần 2 mình sẽ đưa ra một số ví dụ để các bạn hiểu hơn về format string và một phần nào đó khai thác lỗi này như thế nào.

securitydaily