Github avatar

GyeongSu Han's Github Pages

Pwnable.kr random

Jul 23, 2016 · Wargame

문제는 다음과 같다.

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

랜덤한 값과 입력한 값을 xor연산을 한 결과가 0xdeadbeef를 만들면 되는 문제이다.

이 문제를 풀기 위해 다음의 코드를 살펴보자.

#include <stdio.h>

int main() {
  unsigned int random;
  random = rand();

  printf("rand() : %d\n", random);
  return 0;
}

이 코드는 랜덤 값을 출력하는 프로그램이다. 이 프로그램을 실행하면 다음과 같은 결과를 볼 수 있다.

random@ubuntu:/tmp/micalgenus$ ./random
rand() : 1804289383
random@ubuntu:/tmp/micalgenus$ ./random
rand() : 1804289383
random@ubuntu:/tmp/micalgenus$ ./random
rand() : 1804289383
random@ubuntu:/tmp/micalgenus$ ./random
rand() : 1804289383

항상 같은 결과를 볼 수 있다. 이 이유는 rand함수의 특징 때문에 그러는데, rand의 경우 시드를 받아 그 값을 이용하여 연산을 하는 함수이다.

rand를 하기 전에 srand(time(NULL))을 자주 해주는데, srand는 rand의 초기값을 설정해 주는 함수이다.

이 초기값을 이용하여 연산한 결과를 rand로 반환해 주는데, 초기값을 time(NULL)을 넣어주었기 때문에 항상 다른 초기값이 들어가게 된다.

하지만 이 프로그램의 경우는 srand를 하는 부분이 없기 때문에 항상 같은 값을 가지고 오게 된다. 그러므로 만들어야할 값을 예측할 수 있다.

random@ubuntu:~$ ./random
3039230856
Good!
Mommy, I thought libc random is unpredictable...