2011-12-17 33 views
8

Xin chào tất cả,Sự khác nhau giữa việc khai báo shellcode là mảng char [] và char *?

Tôi đang cố gắng tìm hiểu mã shellcoding cơ bản và tôi đã chạy trên một cái gì đó tò mò mà tôi hy vọng ai đó có thể giải thích cho tôi. Tôi đã biên dịch mã sau đây theo hai cách: khai báo shellcode như một mảng và như một char *. Khi tôi khai báo shellcode như một mảng, linux phát hiện rằng tôi đang cố gắng thực hiện dữ liệu và tôi nhận được một segfault trên lệnh đầu tiên. Tuy nhiên, khi tôi khai báo shellcode như là một char * tất cả các shellcode thực hiện và tôi nhận được một "Hello world!". Trình biên dịch xử lý hai khai báo này khác nhau như thế nào và tại sao một trình kết thúc trong shellcode tồn tại trong bộ nhớ không được bảo vệ? Cảm ơn trước.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

/* This declaration ends in a segfault */ 
//char shellcode[] = 

/* This declaration ends in successful execution */ 
char* shellcode = 

/* Shellcode prints "Hello world!" and exits */  
"\xeb\x1f\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x0c\xcd\x80\x48\x31\xc0\xb0\x01\x48\x31\xdb\xcd\x80\xe8\xdc\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21"; 

int main() 
{ 
    void (*f)(); 
    f = (void (*)())shellcode; 
    (void)(*f)(); 
} 

Trả lời

8

Khi bạn khai báo dưới dạng char[], bộ nhớ nằm trên ngăn xếp. Khi bạn khai báo nó như là một char* và gán nó một chuỗi ký tự, bộ nhớ nằm trong chính hình ảnh thực thi. Linux không thích bạn thực thi mã trên ngăn xếp, nhưng tốt với bạn thực hiện bộ nhớ trong phần đó của hình ảnh thực thi. Đó là bởi vì nó đang cố gắng tránh một loại tấn công tràn ngăn xếp nhất định, nơi mọi người có thể tràn ngăn xếp bằng một số lệnh tùy ý và sau đó thực hiện chúng.

Bạn có thể sử dụng mprotect trên Linux để đặt quyền cho khu vực bộ nhớ hoặc VirtualProtectEx trên Windows. Bằng cách đó bạn có thể thiết lập rõ ràng các quyền của bộ nhớ có thể thực thi được.

3

Trong trường hợp đầu tiên của bạn:

char shellcode[] = 

Điều này đặt các chuỗi chữ trên stack như một mảng địa phương. Bộ nhớ ngăn xếp và bộ nhớ heap thường không có quyền thực thi (vì lý do rõ ràng về bảo mật).

Trong trường hợp thứ hai của bạn:

char* shellcode = 

Chuỗi sống trong bộ nhớ tĩnh - thường ở cùng vùng với phần còn lại của chương trình nhị phân - đó là thực thi.

Các vấn đề liên quan