tmxklab

[Pwnable.xyz] Jmp_table 본문

War Game/Pwnable.xyz

[Pwnable.xyz] Jmp_table

tmxk4221 2020. 4. 9. 22:16

1. 문제

nc svc.pwnable.xyz 30007

 

1) 문제 확인

- 1) Malloc : size값 만큼 메모리 할당

- 2) Free : 메모리 해제

- 3) Read : Input값 저장

- 4) Write : Input값 출력

 

2) 함수 확인

 

2-1) 메인 함수

- v3값에 따라 vtable에 지정된 함수를 호출

- vtable이 뭔지는 이따가 확인해보자

 

2-2) _()

- 요거를 호출해야 한다.

 

2-3) do_malloc()

- input값으로 size를 받고 result에 할당된 메모리 주소를 넣는다.

- result값이 존재하면 heap_buffer(bss영역)에 주소 값 저장하고 아니면 1을 저장

 

2-4) do_read()

- heap_buffer가 존재하는 경우 heap_buffer에 size값 만큼 표준 입력을 저장

 

2-5) do_write()

- heap_buffer가 존재하는 경우 heap_buffer에 size값 만큼 표준 출력

 

2-6) do_free()

- heap_buffer가 존재하는 경우 메모리 해제

 

3) 메모리 보호기법 및 파일 정보 확인

 


 

2. 접근 방법

일단, _()를 호출해야하는 것을 명심하자

주소 값 : 0x400a31

 

그리고 아까 main함수에서 vtable의 인덱스 값에 따라 호출하는 함수가 다르다고 하였다.

- vtable의 주소 값 : 0x6020c0

- vtable에 menu에 따라 실행할 함수들의 목록이 포함되어 있다.

 

이제, 디버깅을 통해 vtable이 어떻게 동작하는지 확인해보자

 

1) 디버깅

이 부분이 vtable의 인덱스 값을 받아 vtable에 존재하는 어떤 하나의 함수를 호출하는 부분이다.

- v3[rbp-0x4] : vtable의 인덱스

- v3[rbp-0x4]의 값을 eax에 저장하고(현재 1을 입력하였음)

- rdx에 rax*8 (현재 rax는 1)의 주소 값을 저장한다.(결과 : rdx = 0x8)

- vtable의 주소 값을 rax에 저장

- rdx(0x8) + rax(vtable주소 값)을 다시 rax에 저장한다.

- 그 다음 rdx에 저장하고 rdx를 호출한다.

- 결국 call [index*8 + vtable의 주소 값]이 된다.

 

vtable확인)

- vtalbe의 시작주소로 부터 8bytes씩 어떠한 함수의 주소 값이 저장되어 있다.

- 이 함수들은 아까 아이다에서 봤던 do_exit, malloc, free, read, write함수이다.

- 아까 1을 넣은 경우 [1*8 + vatlbe 시작주소]의 값이 rdx에 들어가 call을 하게 된다.

 

이처럼 인덱스와 vtable의 시작주소를 참조하여 call rdx를 하게 되는데 만약에 0과 양수 값이 아닌 음수 값을 넣었을 때는 어떻게 될까???

 

메뉴에서 -1을 입력한 경우)

- -1을 입력하면 처음에 rax에 0xffff ffff ffff ffff가 들어가게 되고

- rdx에 [rax*8]을 통해 위 사진 처럼 0xffff ffff ffff fff8이 들어가게 된다. 

- 그리고 위 인스트럭션 부분에 vtable의 시작 주소와 input값을 더한 주소에 들어있는 값을 rax로 옮기고 최종적으로 다시 rdx로 옮긴다.

 

- rdx + rax = 0x6020b8이며, 0x6020b8에 존재하는 값을 확인해보면

- 따라서, rdx에는 0x1이 들어가고 call rdx를 하게 되면

- 세그먼테이션 폴트가 뜬다.

 

아까 -1을 넣었을 경우 주소 값이 0x6020B8(heap_buffer)이었다.

heap_buffer변수는 vtable의 시작주소인 0x6020C0과 8bytes만큼 떨어져 있다.

 

즉, 우리는 heap_buffer에 있는 값을 호출할 수 있다.

heap_buffer에는 초기 값으로 0x1이 들어있으며 메모리 할당이 실패하거나 free될 경우 0x1이 설정된다.

- do_malloc() line 13

- do_free() line 9 ~ 10

 

do_read()에서 heap_buffer에 값을 넣을 수 있다.

- do_read() line 8

 

하지만, read를 하려면 heap_buffer가 malloc을 통해 메모리가 할당받아야 되며, 메모리가 할당되면 heap_buffer에는 메모리가 할당된 영역의 주소가 들어간다.

- heap_buffer에 메모리 할당된 주소값이 들어있음

 

따라서, heap_buffer에 원하는 주소 값을 넣을 수 없다

그런데 vtable로부터 16bytes 떨어진 곳에 size변수가 존재한다.

 

size변수를 입력하는 곳은 이 부분이다.

- do_malloc() line 6 ~8

그리고 size값은 입력 후 값이 변하지 않는다.

 

결론)

  • size(0x6020B0)에 _()의 주소 값을 넣는다.
  • menu에 -2을 입력하여 vtable로부터 -16bytes 떨어져 있는 size변수에 있는 _()주소 값을 호출한다.

 


 

3. 풀이

1) size에 _()주소 값 입력

- _()의 주소 값 : 0x400a31 → 4,196,913

- do_malloc()의 size값을 입력하는 부분에서 4,196,913을 입력한 결과

 

2) menu에 -2를 입력한 경우

- rdx(size)에 존재하는 _()함수의 주소 값을 호출한다.

 

3) 공격 실행

'War Game > Pwnable.xyz' 카테고리의 다른 글

[Pwnable.xyz] Game  (0) 2020.04.13
[Pwnable.xyz] I33t-ness  (0) 2020.04.09
[Pwnable.xyz] TLSv00  (0) 2020.04.09
[Pwnable.xyz] two target  (0) 2020.04.09
[Pwnable.xyz] xor  (0) 2020.04.09
Comments