Phát triển khai thác có thể dẫn đến những cơn đau đầu nghiêm trọng nếu bạn không tính toán đầy đủ các yếu tố giới thiệu e không xác định vào quá trình gỡ lỗi. Cụ thể, địa chỉ ngăn xếp trong trình gỡ lỗi có thể không khớp với địa chỉ trong quá trình thực thi thông thường. hiện tượng này xảy ra bởi vì hệ điều hành nạp đặt cả hai biến môi trường và lập luận chương trình trước đầu của ngăn xếp:

Kể từ khi chương trình dễ bị tổn thương của bạn không mất bất kỳ đối số, các biến môi trường có nhiều khả năng thủ phạm . Mare chắc chắn rằng họ là như nhau trong cả hai invocations, trong vỏ và trong trình gỡ lỗi. Để kết thúc này, bạn có thể quấn gọi của bạn trong env
:
env - /path/to/stack
Và với trình gỡ lỗi:
env - gdb /path/to/stack
($) show env
LINES=24
COLUMNS=80
Trong ví dụ trên, có hai biến môi trường được thiết lập bởi gdb, mà bạn có thể tiếp tục vô hiệu hóa :
unset env LINES
unset env COLUMNS
Bây giờ show env
phải trả về danh sách trống. Tại thời điểm này, bạn có thể bắt đầu quá trình gỡ lỗi để tìm địa chỉ ngăn xếp tuyệt đối mà bạn hình dung để nhảy tới (ví dụ: 0xbffffa8b
) và mã hóa nó vào khai thác của bạn.
Một chi tiết tinh tế nhưng quan trọng khác: có sự khác biệt giữa việc gọi ./stack
và /path/to/stack
: vì argv[0]
giữ chương trình chính xác cách bạn gọi, bạn cần đảm bảo chuỗi yêu cầu bằng nhau. Đó là lý do tại sao tôi đã sử dụng /path/to/stack
trong các ví dụ trên và không chỉ là ./stack
và gdb stack
.
Khi học tập để khai thác với các lỗ hổng an toàn trí nhớ, tôi khuyên bạn nên sử dụng chương trình wrapper dưới đây, mà làm việc nặng nhọc và đảm bảo ngăn xếp offsets bằng:
$ invoke stack # just call the executable
$ invoke -d stack # run the executable in GDB
Đây là kịch bản:
#!/bin/sh
while getopts "dte:h?" opt ; do
case "$opt" in
h|\?)
printf "usage: %s -e KEY=VALUE prog [args...]\n" $(basename $0)
exit 0
;;
t)
tty=1
gdb=1
;;
d)
gdb=1
;;
e)
env=$OPTARG
;;
esac
done
shift $(expr $OPTIND - 1)
prog=$(readlink -f $1)
shift
if [ -n "$gdb" ] ; then
if [ -n "$tty" ]; then
touch /tmp/gdb-debug-pty
exec env - $env TERM=screen PWD=$PWD gdb -tty /tmp/gdb-debug-pty --args $prog "[email protected]"
else
exec env - $env TERM=screen PWD=$PWD gdb --args $prog "[email protected]"
fi
else
exec env - $env TERM=screen PWD=$PWD $prog "[email protected]"
fi
'seg faults' là do tràn bộ nhớ đệm, bạn đã làm, chính xác Khi bạn chạy hệ điều hành mã của bạn gửi SIGSEGV đến quá trình của bạn (= chương trình trong thực hiện) về vi phạm bộ nhớ mà cung cấp cho bạn thông điệp Segmentation Fault - tín hiệu này là do để bạn đang truy cập không hợp lệ vào bộ nhớ hợp lệ. (Tôi đoán bạn đang cố gắng để viết/sửa đổi trên '" constantstring "' ở cuối) –
... Tôi biết điều đó. Nó là vụ phải thực hiện một vỏ. Trong GDB nó thực thi shell. Khi tôi chạy chương trình bên ngoài GDB nó không chạy vỏ, do đó segfault – thaweatherman
điều này là bởi vì khi bạn chạy mã của bạn bên ngoài GDB nó - nó không xác định hành vi trong tiêu chuẩn C. Trong khi GDB xử lý tín hiệu SIGSEGV để nó có thể cho bạn điểm đến lỗi phân đoạn –