본문 바로가기

Hacking & Security/Exploit

diff 32bit vs 64bit

diff 32bit vs 64bit


General BOF


EBP-8에 할당되어 있는 변수를 오버플로우 한다고 가정하였을때,

EBP에는 SFP가 존재하고, EBP+4에는 RET이 존재한다.

32bit system에서는 SFP가 4byte크기를 갖기 때문에 RET 변조를 위해서는 최소 스택 + 4 byte의 더미를 주고 RET에 접근한다.

하지만 64bit system의 경우에는 4byte 주소를 사용하던 32bit와는 달리 8byte 주소를 사용한다.

따라서, SFP가 8byte이므로 스택 + 8byte만큼의 더미를 주어야 한다.

RTL and ROP


이에 대해 학습하기 이전에는 Calling Convention에 대한 이해가 필요하다.

콜링 컨벤션은 크게 3가지 존재하며 여기서 주목할 것은 cdeclfastcall이다.

두 가지의 호출규약의 가장 큰 차이는 인자를 전달하는 방식이다.

cdecl : 스택 , fastcall : 레지스터 를 사용하여 인자를 전달한다.

32bit system에서의 RTL Payload는 아래와 같다. (ebp-8 Overflow)

payload = ''
payload += 'A' * (8 + 4)
payload += p32(system)
payload += 'A' * 4
payload += p32(binsh)

EBP까지의 거리 + SFP 크기의 더미를 주어 RET에 접근하기 위해 스택을 채우고 RET위치를 system 함수의 주소로 Overwrite한다. 그 이후 4byte는 system함수가 호출된 이후 호출 될 주소를 의미한다.

그리고 그 다음 4byte는 system이 끝나고 호출 될 주소이다. (위 예시에서는 binsh의 주소)

그 뒤 4byte는 첫번째 인자로 들어간다.

64bitSystem에서는 어떠한 레지스터에 몇번째 인자가 들어가는지 알고있어야 한다.

RDI, RSI, RDX, RCX순으로 인자가 들어간다.

이를 바탕으로 64bit System에서의 RTL Payload를 펴보자. (ebp-8 Overflow)

payload = ''
payload += 'A' * (8 + 8)
payload += p64(pr)    # pop rdi, ret , 첫번째 인자 pop
payload += p64(binsh)
payload += p64(system)

64 bit 체제에서는 ret에 바로 함수 주소를 쓸 수 없기 때문에, gadget을 이용해야한다.

(만일, 인자가 없는 함수의 경우에는 그냥 써도 무방하다.)

위 예시에서 쓰인 system함수는 인자가 하나인 함수이며 따라서 첫 번째 인자가 들어갈 레지스터인 RDIpop해줘야 한다.

먼저, pop을 이용해서 첫 번쨰 인자가 위치할 rdi내부 값을 빼주고, binsh 문자열을 넣은 뒤, system함수를 호출한다.

'Hacking & Security > Exploit' 카테고리의 다른 글

Return To Libc ( RTL )  (0) 2018.12.29
Return to Shellcode  (0) 2018.12.27
Basic of pwnable  (0) 2018.12.27
BOF 기초문서  (0) 2018.11.03