tôi đang làm việc trên một phòng thí nghiệm lỗ hổng định dạng chuỗi, nơi chúng tôi đang đưa ra đoạn mã sau:Truy cập vào yếu tố thứ 2 của một mảng trong một cuộc tấn công lỗ hổng chuỗi định dạng
#define SECRET1 0x44
#define SECRET2 0x55
int main(int argc, char *argv[])
{
char user_input[100];
int *secret;
int int_input;
int a, b, c, d; /* other variables, not used here.*/
/* The secret value is stored on the heap */
secret = (int *) malloc(2*sizeof(int));
/* getting the secret */
secret[0] = SECRET1;
secret[1] = SECRET2;
printf("The variable secret's address is 0x%.8x (on stack)\n", &secret);
printf("The variable secret's value is 0x%.8x (on heap)\n", secret);
printf("secret[0]'s address is 0x%.8x (on heap)\n", &secret[0]);
printf("secret[1]'s address is 0x%.8x (on heap)\n", &secret[1]);
printf("Please enter a decimal integer\n");
scanf("%d", &int_input); /* getting an input from user */
printf("Please enter a string\n");
scanf("%s", user_input); /* getting a string from user */
/* vulnerable place */
printf(user_input);
printf("\n");
/* Verify whether your attack is successful */
printf("The original secrets: 0x%x -- 0x%x\n", SECRET1, SECRET2);
printf("The new secrets: 0x%x -- 0x%x\n", secret[0], secret[1]);
return 0;
}
Chúng tôi không được phép chỉnh sửa mã. Chỉ sử dụng đầu vào, chúng tôi có 4 mục tiêu: làm hỏng chương trình, in giá trị bí mật [1], sửa đổi giá trị bí mật [1] và sửa đổi giá trị bí mật [1] thành giá trị được xác định trước.
Mẫu đầu ra tôi nhận được là:
The variable secret's address is 0xbfffe7cc (on stack)
The variable secret's value is -x0804a008 (on heap)
secret[0]'s address is 0x0804a008 (on heap)
secret[1]'s address is 0x0804a00c (on heap)
Please enter a decimal integer
65535
Please enter a string
%08x.%08x.%08x.%08x.%08x.%08x.%08x%08x.
bfffe7d0.00000000.00000000.00000000.00000000.0000ffff.0804a008.78383025
Vì vậy, bằng cách nhập 8 "% 08x" s, tôi in địa chỉ của bí mật + 4, sau đó tôi in địa chỉ của ints a, b, c, và d - nhưng như tôi chưa bao giờ cho họ một giá trị, họ không chỉ bất cứ nơi nào và chỉ hiển thị 0. Sau đó là số thập phân tôi nhập vào, được chọn sao cho 'ffff' sẽ hiển thị rõ ràng. Tiếp theo là địa chỉ của bí mật [0], sau đó tôi nhận được vào các giá trị khác được lưu trữ trong chương trình.
Nếu tôi nhập AAAA.%08x.%08x.%08x.%08x.%08x.%08x.%08x%08x.
, sau .0804a008 sẽ là .41414141, bởi vì A từ đầu vào chuỗi sẽ được lưu trữ ở đó.
Thật dễ dàng để phá vỡ chương trình: đủ% s trên đầu vào chuỗi gây ra sự phân đoạn. Bây giờ tôi cần phải đọc giá trị bí mật [1], mặc dù, và tôi hoàn toàn bị mất. Tôi cố gắng đặt địa chỉ trên ngăn xếp bằng cách nào đó, bằng cách đặt nó vào đầu chuỗi như vậy: \xd0\xe7\xff\xbf_%08x.%08x.%08x.%08x.%08x.%08x.%s
, nhưng địa chỉ không bị đẩy vào bất kỳ đâu và tôi chỉ cần in bí mật [0] (mà, cho tò mò, là 'D'). Tôi đã thử tất cả các loại địa chỉ, nhưng sau một thời gian tôi nhận ra rằng tôi chỉ lưu trữ tất cả chúng như là một chuỗi nơi mà những người A đã xuất hiện trước đó. Chúng không được chuyển đổi thành hex hoặc bất cứ thứ gì.
Tôi đã nhìn thấy rất nhiều cuộc thảo luận về mã này trên SA và những nơi khác, nhưng tôi chưa thấy ai nói về cách bạn nhận được các giá trị bí mật [1].
Mọi trợ giúp sẽ được đánh giá cao.
Yup, đây là những gì tôi đã mất tích. Cảm thấy như một thằng ngốc TOTAL sau khi tìm ra điều này. Cảm ơn bạn! – Max