TOOR

[TOOR] 19.1 Stack Pivot

lmxx 2023. 12. 6. 13:22
728x90
반응형

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

출처
https://velog.io/@silvergun8291/Stack-pivoting

  1. SFP에는 fake stack, RET에는 read@plt, 그 아래에는 leave-ret 가젯으로 스택을 구성
  2. 에필로그에서 leave 명령이 수행되면 RBP는 fake stack1의 바닥을 가리키게 되고 RSP는 read@plt를 가리키게 된다.
  3. 에필로그에서 RET 명령이 수행되면 read 함수가 실행되게 되어 fake stack에 입력받게 된다.

  1. leave 명령어가 실행되면 RSP는 fake stack1의 RBP 밑의 명령어를 가리키게 되고 RBP는 fake stack2의 바닥을 가리키게 된다.

  1. 이후 쭉 명령어가 실행되다가 read 함수가 실행되면 fake stack2에 입력을 받게 된다 .

  1. 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
이 글은 옵시디언을 이용해서 작성되었습니다.

728x90
반응형