개요
Stack Pivoting은 쓰기 가능한 영역에 Fake Stack을 구성해놓고 Chaining하는 기법이다. 해당 기법은 아래와 같을 때 사용한다.
ROP를 사용하기에 buffer의 사이즈가 작은 경우main함수로 돌아갈 수 없는 경우
함수의 SFP를 이용하여 rbp,rsp 레지스터를 조작하여 fake stack으로 실행 흐름을 옮긴 뒤 미리 작성해둔 fake stack의 코드를 실행해 exploit을 할 수 있게 된다.
선제조건
보통 Stack Pivoting은 bss 영역을 사용하는데 위의 경우가 아니더라도 stdout or stdin의 주소를 알아내거나 File stream을 임의로 조작할 때 사용할 수도 있다. 우선 Stack Pivoint기법을 사용하기 위해선 아래와 같은 조건들이 필요하다.
ret를 덮어쓸 수 있어야 한다.leave retgadget이 있어야 한다.
leave ret?
leave ret은 함수의 에필로그라고 불리는 부분이다. 각각의 역할은 아래와 같다.
- leave 명령어
mov rsp, rbp
pop rbp
- ret 명령어
pop rip
jmp rip
각각의 명령어는 위와 같은 역할을 하며 Stack 영역을 SFP(Stack Frame Pointer)를 참조해 재설정한다. 이때, 우리가 SFP와 RET를 변조해 code의 흐름을 Fake Stack으로 옮겨서 원하는 exploit이 가능해지게 되는 것이다.
주의할 점
만약 bss영역을 Fake Stack으로 재설정할 경우 bss 영역에 있는 stdout과 stdin을 조심해서 사용해야 한다. 만약 이 값들을 overwrite할 경우 입출력을 받는 함수를 사용할 때 에러가 발생할 수 있다. 하지만 이를 이용해 stdout, stdin을 적절히 overwrite한다면 원하는 값을 leak할 수도 있게 된다.