Pwnable.kr의 여섯 번째 문제인 random을 풀어보려고 한다 ~ 💪
생각보다 손쉽게 풀 수 있었다..
바로 문제풀러 가보자! Go!
사이트 접속 시, flag와 random과 random.c 파일이 보인다.
우선 바이너리 파일을 실행시켜보자..
바이너리 파일을 실행시켜보면, 사용자의 입력값을 한 번 받고 종료한다..
바로 소스코드를 확인해보자. random.c는 아래와 같다.
#include <stdio.h>
int main(){
unsigned int random;
random = rand(); // random value!
unsigned int key=0;
scanf("%d", &key);
if( (key ^ random) == 0xdeadbeef ){
printf("Good!\n");
system("/bin/cat flag");
return 0;
}
printf("Wrong, maybe you should try 2^32 cases.\n");
return 0;
}
코드는 엄청 간단하다!
rand() 함수를 통해 랜덤한 숫자를 random이라는 변수에 넣고, 사용자의 입력 값을 받는다.
그 후 if문에서 사용자의 입력 값과 random 변수의 있는 값을 xor 해서 0xdeadbeef면 flag를 보여준다..
rand 함수를 어떻게 유추하냐는 고민이 들 것 같지만, 유추할 필요가 없다...
rand 함수는 의사난수를 생성하는 함수로, 의사난수란 난수를 흉내낸 수이다. 따라서 rand 함수를 시드없이 호출할 경우 첫 번째 값의 경우, 프로그램 실행 시 마다 동일하다.
즉, 프로그램을 실행할 때 마다 동일한 값을 출력하는 허점을 이용하면 된다❗
직접 확인하기 위해 random.c를 가져와서 random 값을 찍어보았다.
#include <stdio.h>
int main(){
unsigned int random;
random = rand(); // random value!
printf("random value : %d\n", random);
unsigned int key=0;
scanf("%d", &key);
if( (key ^ random) == 0xdeadbeef ){
printf("Good!\n");
system("/bin/cat flag");
return 0;
}
printf("Wrong, maybe you should try 2^32 cases.\n");
return 0;
}
결과는 아래와 같다...!
3번정도 반복실행하여 확인했다.. 결과는 1804289383으로 동일하였다!
이제 Key 값만 계산해주면 된다!
XOR의 특징으로는 x^y=z라면, x^z=y, z^y=x가 성립한다.
key ^ 1804289383 = 0xdeadbeef(=3735928559)
key = 1804289383 ^ 0xdeadbeef(=3735928559)
key = 3039230856
즉 사용자의 입력값으로 3039230856 값을 넣으면 Flag를 획득할 수 있다!
🚩 Flag 획득!