문제

I'm having some trouble with a problem I found. Given the following:

int match(char *s1, char *s2) {
    while( *s1 != '\0' && *s2 != '\0' && *s1 == *s2 ){
        s1++; s2++;
    }
    return( *s1 - *s2 );
}

int main() {
    char str1[8], str2[8];
    scanf("%s", str1);
    scanf("%s", str2);
    if (match(str1, str2) == 0)
        printf("They are the same.\n");
    else
        printf("They are not the same.\n");
}

What two input strings of different values can be used to cause the program to print the message "They are the same"? (The code above can not be altered)

I understand that when the arrays are added to the stack, they are "pushed" into it and information is written in the same direction. So if I were to enter "AAAAAAAAA" (A x 9) to str2, it would overflow and str1 would print "A".

My first attempts were to enter A x 16 for str2, hoping that the program would overwrite the value in str1 with 8 A's and the program would only read 8 values in str2. str1 did have a value of A x 8, but str2 retained its value of A x 16.

Is there a way to use this to solve this problem? Or am I thinking about this the wrong way?

EDIT: This problem was meant to be run on a specific machine with an outdated, therefore vulnerable, version of Linux. I've run the program through gdb and it shows that the two strings are next to each other in memory and that str2 is overflowing into str1. My question then, is can I use this to make str2 and str1 look identical to the program when it compares them?

도움이 되었습니까?

해결책 2

I have another idea: What happens if you enter "A" and "A A"? According to this, sscanf expects non-whitespace characters for '%s' , so it will stop reading after the first "A" in "A A" (note the space character). The tag "buffer-overflow" is misleading.

다른 팁

What two input strings of different values can be used to cause the program to print the message "They are the same"? (The code above can not be altered)

No such well-defined scenario exists. The requirements make no sense.

I understand that when the arrays are added to the stack, they are "pushed" into it and information is written in the same direction. So if I were to enter "AAAAAAAAA" (A x 9) to str2, it would overflow and str1 would print "A".

That is not correct. The buffer str1 (which can contain 7 letters + 1 null termination) would overflow and from there anything can happen, you invoke undefined behavior. Some examples of possible undefined behavior is: segmentation fault/crash & burn, or the program appearing to work correctly.

There are no guarantees that str2 is allocated adjacently to str1. Nor are there any guarantees that str1 is allocated before str2. There aren't even any guarantees they are allocated on the stack, although that's quite likely.

Is there a way to use this to solve this problem?

No.

Or am I thinking about this the wrong way?

Yes.

Have you tried the other way around? It depends on how the stack is laid out. I'd try "AAAAAAAAAA" forstr1 and "AAAAAAA" (7x'A') for str2. AFAIR the stack grows form top to bottom.

See here for an explanation.

EDIT: I know evil (undefined) things will happen if you write over the array limits, but the question explicitly tells not to alter the program. Looks like an exercise to understand security risks in software development.

Overwriting your buffer invokes undefined behaviour. Anything can happen, so you must never rely on it.

Also, str1 and str2 are not necessarily next to each other in memory, and you cannot depend on that.

Possible solution

char buffer[16];
char * str1 = &buffer[8];
char * str2 = &buffer[0];

This way you can overflow from str2 to str1 safely (but not from str1 to str2). You should still have proper length checks though.

What two input strings of different values can be used to cause the program to print the message "They are the same"?

Your function for string comparison is wrong. return( *s1 - *s2 ); makes no sense here. Change function to

int match(char *s1, char *s2) {
    while( *s1 != '\0' && *s2 != '\0') {
        if(*s1 != *s2 )
             return 1;
        s1++; s2++;
    }

    return 0;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top