tmxklab
[Pwnable.xyz] Jmp_table 본문
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 |