시작
안녕하세요 :D
오늘은 random
을 풀어볼까 합니다.
순서대로 풀려고 했는데 많이 어렵네요ㅎ.. 쉬운 것 풀고 어려운 문제를 고민해보도록 하겠습니다.
시작해보죠!
root@goorm:/workspace/LCH_Server# ssh random@pwnable.kr -p2222
Write UP
random@ubuntu:~$ ./random
1234
Wrong, maybe you should try 2^32 cases.
random
을 실행해보니 사용자의 입력을 기다립니다.
임의의 숫자를 넣어주니깐 틀렸으니깐 2^32
번 시도해 보라고 하네요.
무리..겠죠? random.c
를 확인해봅시다.
random@ubuntu:~$ cat random.c
#include
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
변수에 넣어주고 있습니다.
사용자는 key
에 입력을 하네요.
두 변수를 XOR
한 값이 0xDEADBEEF
이면 flag
를 출력해 줍니다.
우리가 집중해서 봐야할 부분은 rand()
함수입니다.
rand()
함수에 seed
를 주지 않고 있습니다.
변칙적인 seed
값이 있다면 rand()
함수에서 매번 다른 값이 나오지만
이 코드에서는 rand()
만 사용하고 있네요!
따라서 생성되는 랜덤값은 규칙적입니다.
gdb
로 뜯어볼까요?
gdb-peda$ disas main
Dump of assembler code for function main:
0x00000000004005f4 <+0>: push rbp
0x00000000004005f5 <+1>: mov rbp,rsp
0x00000000004005f8 <+4>: sub rsp,0x10
0x00000000004005fc <+8>: mov eax,0x0
0x0000000000400601 <+13>: call 0x400500 <rand@plt>
0x0000000000400606 <+18>: mov DWORD PTR [rbp-0x4],eax
0x0000000000400609 <+21>: mov DWORD PTR [rbp-0x8],0x0
0x0000000000400610 <+28>: mov eax,0x400760
0x0000000000400615 <+33>: lea rdx,[rbp-0x8]
0x0000000000400619 <+37>: mov rsi,rdx
0x000000000040061c <+40>: mov rdi,rax
0x000000000040061f <+43>: mov eax,0x0
0x0000000000400624 <+48>: call 0x4004f0 <__isoc99_scanf@plt>
0x0000000000400629 <+53>: mov eax,DWORD PTR [rbp-0x8]
0x000000000040062c <+56>: xor eax,DWORD PTR [rbp-0x4]
0x000000000040062f <+59>: cmp eax,0xdeadbeef
0x0000000000400634 <+64>: jne 0x400656 <main+98>
0x0000000000400636 <+66>: mov edi,0x400763
0x000000000040063b <+71>: call 0x4004c0 <puts@plt>
0x0000000000400640 <+76>: mov edi,0x400769
0x0000000000400645 <+81>: mov eax,0x0
0x000000000040064a <+86>: call 0x4004d0 <system@plt>
0x000000000040064f <+91>: mov eax,0x0
0x0000000000400654 <+96>: jmp 0x400665 <main+113>
0x0000000000400656 <+98>: mov edi,0x400778
0x000000000040065b <+103>: call 0x4004c0 <puts@plt>
0x0000000000400660 <+108>: mov eax,0x0
0x0000000000400665 <+113>: leave
0x0000000000400666 <+114>: ret
End of assembler dump.
rand()
호출 직후인 main+18
의 rbp-0x4
속에 rand()
로 생성된 난수가 들어있겠죠?
break point
를 걸고 달려봅시다.
gdb-peda$ x/x $rbp-0x4
0x7ffdbd7ca9ec: 0x6b8b4567
랜덤값이 들어가는 rbp-0x4
부분에 0x6b8b4567
이란 값이 들어가있네요!
몇 번을 재실행해봐도 똑같은 값이 나옵니다. 변칙적인 seed
를 주지 않기 때문이죠.
따라서 0x6b8b4567
와 0xdeadbeef
값을 XOR
해준다면 입력해주어야 할 key
값을 얻을 수 있겠네요.
random@ubuntu:~$ python -c 'print 0x6b8b4567 ^ 0xdeadbeef'
3039230856
key
값으로 3039230856
을 주면 되겠습니다.
random@ubuntu:~$ ./random
3039230856
Good!
Mommy, I thought libc random is unpredictable...
마무리
보통 rand()
함수 사용 시 seed
로 현재 시간을 주죠?
seed
가 없다면 rand()
역시 규칙적인 난수를 생성해줄 뿐입니다.
고생하셨습니다! 다음 문제에서 뵙겠습니다 :D
'CTF_Write_UP > pwnable.kr' 카테고리의 다른 글
pwnable.kr : mistake 풀이 (0) | 2019.04.16 |
---|---|
pwnable.kr : passcode 풀이 (0) | 2019.04.14 |
pwnable.kr : bof 풀이 (0) | 2019.04.13 |
pwnable.kr : col 풀이 (0) | 2019.04.12 |
pwnable.kr : fd 풀이 (0) | 2019.04.11 |