ssh level6@io.netgarage.org
rXCikld0ex3EQsnI
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #include <stdio.h> #include <stdlib.h> #include <string.h> enum{ LANG_ENGLISH, LANG_FRANCAIS, LANG_DEUTSCH, }; int language = LANG_ENGLISH; struct UserRecord{ char name[40]; char password[32]; int id; }; void greetuser(struct UserRecord user){ char greeting[64]; switch(language){ case LANG_ENGLISH: strcpy(greeting, "Hi "); break; case LANG_FRANCAIS: strcpy(greeting, "Bienvenue "); break; case LANG_DEUTSCH: strcpy(greeting, "Willkommen "); break; } strcat(greeting, user.name); printf("%s\n", greeting); } int main(int argc, char **argv, char **env){ if(argc != 3) { printf("USAGE: %s [name] [password]\n", argv[0]); return 1; } struct UserRecord user = {0}; strncpy(user.name, argv[1], sizeof(user.name)); strncpy(user.password, argv[2], sizeof(user.password)); char *envlang = getenv("LANG"); if(envlang) if(!memcmp(envlang, "fr", 2)) language = LANG_FRANCAIS; else if(!memcmp(envlang, "de", 2)) language = LANG_DEUTSCH; greetuser(user); } |
일단 strcat 이 쓰인걸 보니, NULL 바이트를 없애고 큰 문자열을 만드는 문제 같다.
username,user_password 를 받고 username 과 greeting을 합치고 난 후에 출력한다.
username과 greeting을 합칠 떄, greeting은 건드릴 수 없으므로 username에 큰 문자열을 전달하는 것 같다.
-----
1 2 | strncpy(user.name, argv[1], sizeof(user.name)); strncpy(user.password, argv[2], sizeof(user.password)); |
여기서 strncpy 를 sizeof(user.name) 만큼 받는데,
문자열은 NULL로 끝을 명시해준다. 따라서 배열 크기 그대로 받아버리면
우리가 배열크기만큼 문자열을 꽉 채워서 입력해줄 경우 NULL을 없애버릴 수 있다.
이 말은, user.name 과 user.password를 합칠 수 있고
user.name 을 더 큰 문자열로 만들어 BOF를 일으킬 수 있다는 뜻이다.
level6@io:/levels$ ./level06 `python -c 'print "A"*40 + " " + "B"*10'`
Hi AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBB
level6@io:/levels$
이 실행 결과를 보면 "A"*40 후에 B 가 10만큼 붙는 것을 볼 수 있다.