[문제]


[풀이]

보호기법 분석

  • 64bits 바이너리
  • 카나리 없음
  • NX bits 존재
  • PIE 없음

 

소스코드 분석 - 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 값 생성
  • scanf로 입력 받은 key 값과 xor 연산한 값이 0xdeadbeef일 때 flag를 출력함
  • 단순히 rand 함수만 이용하게 되면 맨 처음 호출된 값은 random이지만 호출할 때 마다 같은 값을 출력함

→ 진짜 매번 random한 값을 출력하고 싶다면 srand(time(null))과 같은 형태로 사용해야 함

 

🧵 rand 함수

 

문제 해결

💡 호출되는 random 값이 무엇인지 구하여 key ^ random = 0xdeadbeef 역연산하기

 

gdb 분석 - main 함수

gdb-peda$ disass 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 함수로 생성된 random 값은 rax에 저장되었다가 rbp-0x4로 옮겨짐
  • scanf로 입력 받은 key 값은 rbp-0x8 위치에 저장됨

→ rax 레지스터에 0x6b8b4567이라는 random 값이 저장되었음

  • 0x6b8b4567 ^ key = 0xdeadbeef가 되어야 함
    • key = 0x6b8b4567 ^ 0xdeadbeef = 0xb526fb88(3039230856)
    • 0xb526fb88을 입력 값으로 넣어주면 flag를 획득할 수 있을 것
    • 그러나 scanf 함수가 %d 형태로 key 값을 입력 받기 때문에 10진수 형태로 입력해줘야 함

 

pwntool exploit

from pwn import *

s = ssh(user='random', host='pwnable.kr', password='guest', port=2222)
p = s.process(executable="/home/random/random")

p.sendline("3039230856")
print p.recv()


flag

🍒 Mommy, I thought libc random is unpredictable...

'Wargame > Pwnable.kr' 카테고리의 다른 글

[Pwnable.kr] leg  (2) 2022.10.15
[Pwnable.kr] input  (2) 2022.10.15
[Pwnable.kr] passcode  (0) 2022.10.14
[Pwnable.kr] flag  (0) 2022.10.14
[Pwnable.kr] bof  (0) 2022.10.14

+ Recent posts