Thứ Bảy, 7 tháng 11, 2015

Khái niệm lỗ hổng Format String

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.
Để hiểu hơn về lỗi Format String ở phần này chúng ta sẽ đi vào tìm hiểu một số ví dụ sau:
Ví dụ 1: Ta viết một chương trình C đơn giản:
Ví dụ về format string
Ta biên dịch và chạy thử chương trình để xem kết quả:
Format string
Chương trình trên có chức năng là in ra những xâu mà ta gõ từ bàn phím. Chương trình xuất hiện một dòng cảnh báo là do chúng ta khai báo thiếu định dạng nên trình biên dịch đưa ra cảnh báo nhắc nhở những người lập trình. Bây giờ chúng ta thử nhập vào 1 đến 2 giá trị %s để xem có gì khác biệtFormat string phần 2
Như các bạn cũng đã thấy chúng ta chỉ cần thay đổi dữ liệu đầu vào là %s là đã lấy được các thông tin mà người lập trình muốn giấu đi.

Ví dụ 2:

Format string phần 2
Ví dụ này chương trình nghe có vẻ phức tạp hơn với một số hàm như : rand(), srand(), 
  • Rand(): Hàm sinh ra một giá trị ngẫu nhiên trong chương trình này giá trị đó không vượt quá 100.
  • Srand(): Hàm bổ trợ cho hàm rand() có chức năng là làm cho mỗi lần random không đưa ra giá trị trùng nhau.
  • Atoi(): chuyển một chuỗi sang dạng số.
Nhìn qua đoạn code ta thấy chương trình yêu cầu người chơi nhập một code nào đó mà nếu đúng thì người chơi sẽ chiến thắng. Bây giờ ta chạy thử xem chương trình hiện ra điều gì:
Lỗ hổng format string phần 2
Đúng như chúng ta nói ở trên chương trình yêu cầu người dùng nhập tên và một code bí mật nào đó nếu người chơi nhập đúng thì nó sẽ hiện ra một điều thú vị. Ta sẽ thử dùng format string để khai thác xem. Đầu tiên ta cũng thử như ví dụ 1:
Lỗ hổng format string phần 2
Không xuất hiện một địa chỉ hay một chuỗi nào đặc biệt cả như vậy ta thử làm cách khác. Chúng ta vẫn chạy chương trình như bình thường nhưng đến đoạn nhập username chúng ta nhập tên kèm theo định dạng là là %x để xem có chuyện gì xảy ra:
Lỗ hổng format string phần 2
Woa! Chương trình hiện ra một số các địa chỉ hình như là ở trong stack như vậy công việc của ta giờ là tìm trong stack vị trí chứa cái xâu AAAA mà ta nhập vào. Ta thử cho số lượng %x nhiều lên xem:
Lỗ hổng format string phần 2
Thật may mắn trong số các địa chỉ hiện ra chúng ta thấy xuất hiện ở vị trí thứ 8 là 41414141 mà theo bảng ASCII thì 41 là dạng hex của A như vậy chuỗi chúng ta được lưu ở vị trí thứ 8. Nhìn vào đằng trước thấy xuất hiện một số lạ “00000048” có vẻ là code bí mật chăng? Chúng ta thử nhập vào xem thế nào.
Lỗ hổng format string phần 2
You win! vậy suy đoán chúng ta đã đúng. Code bí mật được lưu ở vị trí trước chuỗi mà ta nhập vào. Các bạn cũng có thể thử với một số chuỗi khác.
Qua một hai ví dụ vừa rồi chắc các bạn cũng hiểu thêm phần nào về Format String. Tôi cũng xin dừng phần này ở đây hẹn gặp lại các bạn trong những vấn đề khác.
securitydaily

Không có nhận xét nào:

Đăng nhận xét