2012-11-16 62 views
5

Tôi có một chương trình C nhỏ để khai thác. Và tôi cũng hiểu được logic đằng sau cuộc tấn công được thực hiện. Tuy nhiên, nhiều như tôi thử, nó chỉ là không làm việc cho tôi.Tấn công chuỗi định dạng

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

#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("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 */ 

    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; 
} 

Tôi chỉ cần in địa chỉ và giá trị của bí mật [0] bằng chuỗi định dạng "printf (user_input);"

Tôi đã thử đưa một cái gì đó như "\ x6e \ xaf \ xff \ xff% x% x% x% x% s". nhưng nó không hoạt động. Bất kỳ đề xuất sẽ được đánh giá cao. Cảm ơn rất nhiều.

+1

Nếu bạn muốn in địa chỉ của một cái gì đó, có lẽ bạn nên sử dụng toán tử addressof, '&'. –

+0

+1 cho mã được định dạng tốt. –

Trả lời

8

Điều này trông giống như một bài tập cho một lớp, vì vậy tôi sẽ cung cấp một số gợi ý, nhưng không có giải pháp thực tế.

Bạn đang cố gắng khai thác chương trình này bằng cách cung cấp đầu vào không tin cậy. Có hai lỗi khá rõ ràng ở đây; một là scanf() sử dụng %s, vì bạn có thể tràn bộ đệm và ghi đè lên ngăn xếp. Khác là một lỗ hổng định dạng chuỗi. Ghi đè lên ngăn xếp có thể sẽ không cho phép bạn làm bất cứ điều gì thú vị cho đến khi hàm trả về. Dựa trên phần "xác minh xem liệu cuộc tấn công của bạn có thành công hay không", bạn có thể muốn khai thác lỗ hổng trước đó, vì vậy tôi đoán đó là lỗ hổng định dạng chuỗi.

Dựa trên phần xác minh, bạn sẽ ghi đè bộ nhớ được trỏ đến bởi secret. Cách duy nhất để gây ra printf để ghi vào một vị trí được kiểm soát trong bộ nhớ là sử dụng trình định dạng định dạng %n, ghi con trỏ đã cho.

Bây giờ, mẹo là tìm ra cách đi lên ngăn xếp cho đến khi chúng tôi tìm thấy con trỏ thích hợp. Thuận tiện, có một số nguyên do người dùng điều khiển ngay trước con trỏ trên ngăn xếp. Vì vậy, chúng ta nhập một số với một mô hình dễ phát hiện (có thể là 65535, là ffff trong hex), và sử dụng một chuỗi định dạng với rất nhiều %x s để xem những gì có trong ngăn xếp. Một khi chúng ta thấy rằng, điều tiếp theo trên ngăn xếp nên là con trỏ.

Hmm. Tôi chỉ thử điều này, và hóa ra là nó không đơn giản lắm. Bố cục chính xác của khung ngăn xếp không thực sự liên quan đến thứ tự khai báo; và nó khác nhau giữa các hệ thống khác nhau đối với tôi. Thay vào đó, tôi đã phải sử dụng rất nhiều %lx s, cùng với một chuỗi nổi tiếng ở đầu, và thêm một dòng để in ra con trỏ thực tế, vì vậy tôi sẽ biết khi tôi tìm thấy nó. Sau đó, thay thế %lx tương ứng bằng %n để ghi thông qua con trỏ đó. Có thể dễ nhất chỉ cần thử 20 hoặc hơn %lx s và thay thế từng cái một với %n, cho đến khi bạn quản lý ghi đè lên con trỏ đó.

Nhưng dù sao, hy vọng đó là đủ để bạn bắt đầu. Hãy cho tôi biết nếu bạn có bất kỳ câu hỏi.

+2

Trong thực tế, trên x86_64 có đủ thanh ghi rằng nếu bạn biên dịch với O2 hoặc O3 có thể không có bất cứ điều gì trên ngăn xếp ngoại trừ bộ đệm. –

+0

Ngoài ra, các biến không sử dụng có thể được tối ưu hóa bởi trình biên dịch, do đó, thiết lập thực tế của ngăn xếp có thể không phải là bạn mong đợi. –

+0

Cảm ơn rất nhiều về đầu vào của bạn. Tôi nhận được các địa chỉ lặp lại khi tôi cho% 1x nhiều lần khiến tôi khó hiểu. Tôi hiểu rằng trên stack (cao đến thấp) biến được lưu trữ theo thứ tự, user_input, bí mật, int_input. Vì vậy, nếu tôi cho% 1x 8 lần, tôi sẽ có thể trỏ đến & int_input.bí mật = 0xbffffa5c, user_input = bffffa60, int_input = bffffa58 Vui lòng nhập một số nguyên thập phân Vui lòng nhập một chuỗi % 1x% 1x% 1x% 1x% 1x% 1x% 1x% 1x bffffa60bffffa60bffffa584002c8a440021000400212d810 Những bí mật gốc: 0x44 - - 0x55 Những bí mật mới: 0x44 - 0x55 – shambolic

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