What is Stack Pivoting
특정 중심점을 기준으로 스택이 아니었던 공간을 스택 영역인 것 처럼 사용하는 기법.
- 이 기법을 통해 익스플로잇을 하기 위한 공간이 부족할 때 새로운 스택 영역을 확보할 수 있다.
- 기존의 스택을 리얼 스택이라고 하고 새롭게 확보된 영역을 페이크 스택이라 한다.
- 여러 gadget을 이용해서 쓰기 가능한 공간에 Fake Stack을 구성해놓고 chaining 하는 기법
- fake stack을 위한 공간으로는 보통 bss + 0x300 영역을 사용하고 체이닝할 때마다 0x100 씩 더해서 새로운 공간을 만들어 준다.
- 가젯은 RSP 레지스터의 값을 변조할 수 있는 가젯을 사용한다.
여러 가젯들이 있는데 이중 보통 leave; ret; 가젯을 사용한다.
pop rsp gadget
- 가장 단순하지만 존재할 가능성이 가장 적다.
xchg <reg> ,rsp
- pop <reg> gadget을 찾을 수 있으면 xchg 가젯을 사용하여 RSP의 값으로 바꿀 수 있다.
- 저장된 반환 포인터 다음에 약 16 바이트의 스택 공간이 필요하다 .
pop <reg> <==== return pointer
<reg value>
xchg <rag>, rsp
leave: ret
8바이트만 필요하다.
모든 함수 (main 제외) 는 leave; ret 가젯으로 종료된다.
leave는 아래와 같다.
mov rsp, rbp
pop rbp
따라서 함수 종료는 다음과 같다.
mov rsp, rbp
pop rbp
pop rip
RIP를 덮어쓸 때 RBP를 덮어쓰기 전에 8바이트를 덮어써준다.
leave를 사용해서 rbp를 덮어쓸 수 있다.
leave를 보면 RBP의 값이 RSP로 이동하는 것을 볼 수 있다.
따라서 RBP overwrite 를 호출하면 RIP를 leave 주소로 덮어쓴다.
다시 ret하면 RBP의 값이 RSP로 이동한다.
RIP를 덮어쓰는 것 보다 더 많은 스택 공간이 필요하지 않기 때문에 압축률이 매우 높다.
Stack pivoting을 하기 위한 전제조건
- 페이로드가 저장되어 있는 영역이 존재할 경우, RET 까지만 overflow 발생
- 페이로드가 저장되어 있는 영역이 없는 경우, 입력함수 + leave_ret을 넣을 수 잇을 만큼 overflow 발생
- 두 경우 다 gadget이 존재해야함.
일반적으로 Stack Pivoting을 사용하는 경우
- RET 까지만 overflow 발생 (overflow 가 많이 나지 않음)
- main으로 돌아갈 수 없는 경우 (seccomp 등)
Fake Stack으로 쓸만한 곳을 찾기
주로 bss 영역을 사용한다.
vmmap
을 통해서 권한을 확인하고 r권한, w권한이 있는 곳(0x602000)을 찾는다.
vmmap : 가상 메모리의 레이아웃을 출력해준다.
objdump -h ./binary
VMA (Virtual Memmory Address)
: 섹션이 최종 결과 파일에 올려진 뒤 존재하는 주소를 말한다.
0000000000601060
LMA (Load Memmory Address)
: 섹션이 실제 메모리에 올려지는 물리적인 메모리 주소를 가리킨다.
0000000000601060
exploit
- SFP에는 fake stack, RET에는 read@plt, 그 아래에는 leave-ret 가젯으로 스택을 구성
- 에필로그에서 leave 명령이 수행되면 RBP는 fake stack1의 바닥을 가리키게 되고 RSP는 read@plt를 가리키게 된다.
- 에필로그에서 RET 명령이 수행되면 read 함수가 실행되게 되어 fake stack에 입력받게 된다.
- leave 명령어가 실행되면 RSP는 fake stack1의 RBP 밑의 명령어를 가리키게 되고 RBP는 fake stack2의 바닥을 가리키게 된다.
- 이후 쭉 명령어가 실행되다가 read 함수가 실행되면 fake stack2에 입력을 받게 된다 .
- fake stack1의 leave 명령어가 실행되면 RSP가 fake stack의 바닥을 가리키게 되고 이후 RET 명령이 실행되면 그 이후에 있는 명령들을 실행하게 된다.
7. 최종적으로 system(”/bin/sh”) 명령이 실행되면 셸이 뜬다.
참고 자료
https://velog.io/@silvergun8291/Stack-pivoting
https://jiravvit.tistory.com/entry/Stack-Pivoting-스택-피봇팅
https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting
이 글은 옵시디언을 이용해서 작성되었습니다.
'TOOR' 카테고리의 다른 글
[TOOR] 20. __environ stack address leak (0) | 2023.12.06 |
---|---|
[TOOR] 24.2 cpp_smart_pointer_1 write up (0) | 2023.11.17 |
[TOOR] 24.1. UAF (0) | 2023.11.17 |
[TOOR] 23. Heap chunk 구조 (2) | 2023.10.17 |
[TOOR] 22. FSOP (2) | 2023.10.17 |