-
x64 BOF(Buffer Overflow)System hacking training/Knowledge 2018. 4. 18. 20:32
오늘은 x64 즉 64 bit 환경에서의 buffer overflow에 대해 포스팅하겠습니다.
먼저 x86 vs x64에 대해 선행 지식이 필요합니다.
바이너리 하나를 받았는데 이제서야 풀이해보네요.ㅠ
먼저 바이너리를 확인해보겠습니다.
char buffer가 256 byte로 할당되었지만 gets()의 사용으로 인해 bof가 터집니다.
gets()는 NULL문자가 오기전까지 모든 문자열을 입력받는데 바로 여기서 ret 를 침범하여 우리가 원하는 shell()를 실행할 수 있습니다.
이전의 x86 bof 문제에서 처럼 payload를 구성해보면
[x86 payload]
python -c 'print "A"*256+"SFP(4)"+"ret(4)"'이렇게 buf 를 의미없는 문자로 덮어주고 SFP를 4byte를 덮고 바로 ret를 우리가 원하는 주소로 덮어주었습니다.
하지만 x64에서는 기본적으로 스택의 크기와 레지스터의 크기가 8byte 이기 때문에 SFP를 8byte 덮어줘야합니다.
너무나도 당연한 사실이죠.
그리고 또 중요한 사실은
64 bit 환경에서는 user section에서총 48bit를 사용하기 때문에 return address를 조작하려면
6byte(48bit)의 주소로 덮어줘야합니다.
따라서 x64 에서는 페이로드를 이렇게 구성합니다.
[x64 payload]
python -c 'print "A"*256+"SFP(8)"+"ret(6)"'
x64에서 왜 앞의 2byte를 버릴까..?
이는 주소를 계산하는데 필요없는 시간이 낭비가 되기 때문에 사용하지 않는다.
x86에서 x64로 넘어오면서 2배의 주소공간을 가지게 되었지만
그정도의 주소공간을 필요로 하는 프로그램은 아직은 없기 때문에 앞의 2byte를 사용하지 않는다.
그리고
0x0000 7fff ffff ffff 에서 7이 8로 넘어갈때 (Kernel Section)
운영체제에서는 바로 앞의 4byte 0x0000를 0xffff 로 세팅하여
0xffff 8000 0000 0000가 Kernel Section이 된다.
따라서
64bit 주소체계에서는 User Section은 16bit를 제외한 48byte를 사용하게 된다.
바로 풀이 시작해보겠습니다.
먼저 gdb로 main()에 할당한 스택의 총 크기를 확인해야합니다.
왜 해야하냐..?
SFP 와 buffer 사이에 dummy값이 있다면 이것 또한 채워줘야 ret 에 도달할 수 있기 때문이죠.
하지만 이 바이너리에서는 스택의 크기가 0x110 으로 272 byte 할당되었지만
lea rax, [rbp-0x100] 부분을 통해서 rbp-0x100에 char buf[256]가 위치한것은 알 수 있습니다.
따라서 스택을 그려보면
| char buf[256] | SFP | ret |
이렇게 그릴 수 있습니다.
그렇다면 이제 ret에 넣어줄 shell()의 주소를 구해봅시다.
shell()의 첫 주소는 0x0000004005b6 이네요.
이제 바로 익스하면 됩니다.
A 264 로 SFP(8) 까지 덮어주고 ret 6byte의 shell()의 주소로 덮어주면 쉘을 띄울 수 있습니다.
이상 x64 BOF 에 대한 포스팅을 마치겠습니다.
반응형'System hacking training > Knowledge' 카테고리의 다른 글
What is heap - part1 (2) 2018.12.12 FPO (Frame Pointer Overflow) (0) 2018.04.26 [x86 vs x64] Memory Address (2) 2018.03.19 ELF Memory Protection - RELRO (2) 2018.03.07 ELF Technique - ROP (2) 2018.03.05