
fsb를 애매하게 이해한 것 같아 hackCTF의 babyfsb문제를 푸는데 대체 무슨 기준으로 leak이 되는지.. 등 기초가 많이 부실했구나 느끼게 해 준 문제였습니다
babyfsb write up도 쓸겸 부족한 부분을 정리해볼까 합니다
FSB는 주로 printf함수에서 발생하는 버그인데 포맷 스트링 즉 서식 문자를 잘못 사용하였을 때 생기는 게 됩니다
x64에서는 rdi -> rsi -> rdx -> rcx -> r8 -> r9 -> stack 순으로 인자가 저장됩니다

위의 그림을 참고해서 생각해보면 rdi레지스터에 서식 문자를 지정하여 주고

지정된 서식 문자는 다음의 인자들을 서식 문자에 맞게 출력해주게 됩니다
#include <stdio.h>
int main(){
printf("%lx\n%lx\n%lx\n%lx\n%lx\n%lx\n%lx\n%lx\n");
}
그럼 만약 이런 형태의 코드가 있다고 가정해보면 어떤 순서로 값들이 출력이 될까 생각하면 rdi는 저 서식들의 문자열이 저장된 주소일 것이고 %lx로 출력되는 값들은 x64bit 함수 호출 방식을 따라서 rsi -> rdx -> ... 순으로 출력이 될 것이고 결국엔 stack의 저장된 값을 출력하게 됩니다

위의 코드에서 %lx형식이 총 8번 출력을 하게 되고 printf가 실행되기 직전의 레지스터와 스택의 상태입니다


출력된 값들을 보면 아래의 표와 같이 인자 순서대로 출력이 이루어진 것을 확인할 수 있습니다

해당 문제는 HackCTF의 babyfsb문제입니다 x64bit 바이너리이고 0x40만큼의 데이터를 read함수로 입력받고 printf함수를 통해 buf 배열을 그대로 출력해줌으로써 fsb가 발생합니다

입력한 데이터의 위치를 확인하기 위해 %lx형식으로 총 8번 뒤의 데이터를 leak한 후의 결과입니다
6번째 leak된 데이터로 입력한 AAAA의 데이터가 출력되는 것으로 rsp에 위치하고 있는 것을 알 수 있습니다

main함수에서는 bof와 fsb가 각각 한번씩 이루어지기 때문에 stack_chk_fail함수의 got주소를 main으로 바꿔 카나리만 터지면 연속적으로 fsb가 일어날 수 있도록한 뒤 lib_start_main주소를 leak한뒤 stack_chk_fail의 got를 one_gadget을 덮어 쉘이 실행되도록하였습니다
'pwn > HackCTF' 카테고리의 다른 글
hackCTF / Unexploitable #3 (0) | 2022.03.15 |
---|---|
ezshell (0) | 2022.03.05 |
Keygen (0) | 2021.12.12 |
Unexploitable #1 (0) | 2021.10.19 |
poet (0) | 2021.08.12 |