#include <stdio.h>
#include <string.h>
unsigned long hashcode = 0x21DD09EC;
unsigned long check_password(const char* p){
int* ip = (int*)p;
int i;
int res=0;
for(i=0; i<5; i++){
res += ip[i];
}
return res;
}
int main(int argc, char* argv[]){
if(argc<2){
printf("usage : %s [passcode]\n", argv[0]);
return 0;
}
if(strlen(argv[1]) != 20){
printf("passcode length should be 20 bytes\n");
return 0;
}
if(hashcode == check_password( argv[1] )){
system("/bin/cat flag");
return 0;
}
else
printf("wrong passcode.\n");
return 0;
}
Introduction:
문제를 보면 char형으로 입력받은 20개의 문자를 int형으로 캐스팅 한 후 res라는 변수에 중첩해서 더하는 것을 볼 수 있음. 즉, 입력받은 20개의 문자는 4문자 단위로 나눠져 int형 배열에 저장되며, flag의 내용을 보기 위해서는 이렇게 나뉘어진 int형 배열의 값이 중첩되어 더해진 res변수의 결과값이 "0x21DD09EC"가 되게 하면 됨.
How to solve:
그림 1은 어떻게 하면 res의 값이 "0x21DD09EC"가 되게 할 수 있을지를 확인하기 위해 수행된 실험이다. "0x21DD09EC"를 5로 나눠 10진법으로 나타내었을 때 "113626824"가 나왔고, 이 값에 다시 5를 곱해보니 "568134120"(a)이라는 결과가 나왔다. "0x21DD09EC"을 10진법으로 나타내었을 때의 값은 "568134124"(b)인데, 이는 (a)와 4만큼 차이나는 결과이다. 따라서 flag의 값을 확인하기 위해서는 "113626824"*4 + "113626824"+4의 결과가 입력되어야 할 것이다. 답을 확인하기 위해 그림 2와 같이 결과를 입력하였고, 그림 3과 같은 결과가 도출되었다.
<그림 1> int형 배열 5개의 합이 "0x21DD09EC"가 되어야 하므로 "0x21DD09EC"를 5로 나눠봄
<그림 2> int형 배열의 값과 res의 값을 확인하기 위해 화면에 출력
<그림 3> 계산한 값을 입력한 결과 답을 얻음