-
RandomWargame/Pwnable.kr 2019. 6. 15. 10:53
Problem Random
Daddy, teach me how to use random value in programming! ssh random@pwnable.kr -p2222 (pw:guest)
문제에 대한 소스코드는 다음과 같다.
Source Code
#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 함수의 취약점을 알고 있다면 풀 수 있는 문제이다.
없어도 gdb까보면 알려나rand함수는 random value를 한번 생성하고, 이후에 binary를 재실행 했을 경우에 똑같은 random value를 사용한다는 취약점을 가지고 있다.
진짜 그런지 한번 gdb를 통해 확인해보자.
random@prowl:~$ gdb -q random Reading symbols from random...(no debugging symbols found)...done. (gdb) disas main Dump of assembler code for function main: 0x00000000004005f4 <+0>: push %rbp 0x00000000004005f5 <+1>: mov %rsp,%rbp 0x00000000004005f8 <+4>: sub $0x10,%rsp 0x00000000004005fc <+8>: mov $0x0,%eax 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 0x0000000000400634 <+64>: jne 0x400656 <main+98> 0x0000000000400636 <+66>: mov $0x400763,%edi 0x000000000040063b <+71>: callq 0x4004c0 <puts@plt> 0x0000000000400640 <+76>: mov $0x400769,%edi 0x0000000000400645 <+81>: mov $0x0,%eax 0x000000000040064a <+86>: callq 0x4004d0 <system@plt> 0x000000000040064f <+91>: mov $0x0,%eax 0x0000000000400654 <+96>: jmp 0x400665 <main+113> 0x0000000000400656 <+98>: mov $0x400778,%edi 0x000000000040065b <+103>: callq 0x4004c0 <puts@plt> 0x0000000000400660 <+108>: mov $0x0,%eax 0x0000000000400665 <+113>: leaveq 0x0000000000400666 <+114>: retq End of assembler dump. (gdb) b *main+13 Breakpoint 1 at 0x400601 (gdb) r Starting program: /home/random/random Breakpoint 1, 0x0000000000400601 in main () (gdb) i r eax eax 0x0 0 (gdb) ni 0x0000000000400606 in main () (gdb) i r eax eax 0x6b8b4567 1804289383 (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/random/random Breakpoint 1, 0x0000000000400601 in main () (gdb) i r eax eax 0x0 0 (gdb) ni 0x0000000000400606 in main () (gdb) i r eax eax 0x6b8b4567 1804289383
rand 함수가 호출되는 시점인 *main+13에 breakpoint를 걸고 실행해보면 rand 함수의 return값을 저장하기 위한 레지스터(eax)의 값이 변경되는 것을 볼 수 있다. (0x0 -> 0x6b8b4567)
또한, binary를 재시작 했을 경우에 마찬가지로 eax 값을 확인해보면, 이전 실행 결과와 동일한 것을 확인 할 수 있다.
eax는 함수의 return값을 저장하는 레지스터
https://blog.hexabrain.net/186
if( (key ^ random) == 0xdeadbeef ){ printf("Good!\n"); system("/bin/cat flag"); return 0; }
그러므로, key값(입력받는 값)과 0x6b8b4567값을 xor한 값이 0xdeadbeef가 되어야 하므로 0x6b8b4567과 0xdeadbeef를 xor연산 한 값이 key값(입력받는 값)이 된다.
0x6b8b4567 ^ key == 0xdeadbeef 0x6b8b4567 ^ 0xdeadbeef == key
0x0x6b8b4567 ^ 0xdeadbeef = 0xb526fb88 이고 10진수로 변환하면 3039230856 이 된다. 이 값을 key값으로 넣어서 맞는지 확인해보자.
random@prowl:~$ ./random 3039230856 Good! Mommy, I thought libc random is unpredictable...
끝~
'Wargame > Pwnable.kr' 카테고리의 다른 글
특이점이 온 random (0) 2019.12.29 passcode (0) 2019.12.27 flag (0) 2019.06.14 bof (0) 2019.06.14 collision (0) 2019.06.14