1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #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; } | cs |
rand()함수로 새성되는 난수는 임의로 생성되는 난수는 고정된 값이다. 다시 난수가 생성되어도 고정된 값이 생성된다.
난수를 매번 다르게 발생시키기 위해서는 seed값을 주는 srand()함수를 사용해야 한다.
random = rand(); // random value!
rand()함수로 생성된 난수는 rbp-0x4 영역, 사용자에게 입력받는 key는 rbp-0x8 영역에 저장된다.
key 입력값과 rand()함수로 생성된 값하고 XOR 연산하여 결과가 0xdeadbeef 이면 flag가 실행 됨
1 2 3 4 5 6 7 8 9 10 11 12 13 | 0x0000000000400601 <+13>: callq 0x400500 <rand@plt> 0x0000000000400606 <+18>: mov %eax,-0x4(%rbp) 0x0000000000400609 <+21>: movl $0x0,-0x8(%rbp) 0x0000000000400610 <+28>: mov $0x400760,%eax 0x0000000000400615 <+33>: lea -0x8(%rbp),%rdx 0x0000000000400619 <+37>: mov %rdx,%rsi 0x000000000040061c <+40>: mov %rax,%rdi 0x000000000040061f <+43>: mov $0x0,%eax 0x0000000000400624 <+48>: callq 0x4004f0 <__isoc99_scanf@plt> 0x0000000000400629 <+53>: mov -0x8(%rbp),%eax 0x000000000040062c <+56>: xor -0x4(%rbp),%eax 0x000000000040062f <+59>: cmp $0xdeadbeef,%eax | cs |
(gdb) i r rax
rax 0x6b8b4567 1804289383
rand()로 생성된 난수는 매번 다르게 생성되지 않기 때문에 gdb에서 난수 값을 확인 할 수 있다.
rand()난수 값과 비교0xdeadbeef를 xor연산하면 key 값을 알 수 있음
1 2 3 4 5 6 7 | In [2]: (0x6b8b4567^0xdeadbeef) Out[2]: 3039230856 In [3]: hex(0x6b8b4567^0xdeadbeef) Out[3]: '0xb526fb88' | cs |
random@ubuntu:~$ (python -c 'print "3039230856"')|./random
Good!
Mommy, I thought libc random is unpredictable...